您的位置:首页 > 编程语言 > C语言/C++

codeforces 2016-2017 NTUWFTSC E Lines Game

2017-06-18 20:17 369 查看
Consider the following game about removing N straight line segments on the plane. The segments are numbered from 1 to N.
The i-th segment connects points (0, i) and (1, pi),
where the numbers p1, p2, ..., pN are
a permutation of numbers from 1 to N.
Your are also given N positive integers v1, v2, ..., vN.
On each step, you can select any segment i which is not removed yet, pay vi dollars,
and then remove the i-th segment and all segments intersecting with it. Note that you MUST remove all segments which intersect with i-th
segment.

The purpose of this game is to remove all segments while spending the minimum possible sum of dollars. Please answer how much you need to spend when you play the game with best strategy.

Input

The input consists of three lines. The first line contains an integer N. The second line consists of N integers p1, p2, ..., pN.
The third line consists of N integer v1, v2, ..., vN.

1 ≤ N ≤ 105


 is
a permutation of 1, 2, ..., N

1 ≤ vi ≤ 2 × 104
Output

Output only one number indicating the minimum possible sum of dollars required to remove all segments.

Examples

input
4
2 1 4 3
1 2 3 4


output
4


input
41 2 3 41 2 3 4


output
10


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

计算几何+思路~

我们把所有点极角排序一遍,然后扫描计算每个角对于答案的贡献。

数组又双叒叕开小了,我是不是也应该像柴神那样写个副标题了2333

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long

int n,ans,b[100001],t,x;

struct node{
int x,y;
}a[100002];

node operator - (node u,node v)
{
return (node){u.x-v.x,u.y-v.y};
}

ll operator * (node u,node v)
{
return (ll)u.x*v.y-(ll)u.y*v.x;
}

bool cmp(int u,int v)
{
return a[u]*a[v]>0;
}

int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}
while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}

int main()
{
n=read();
for(int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(),b[i]=i;
sort(b+1,b+n+1,cmp);a[0]=a
;a[n+1]=a[1];
for(int i=1,j=1;i<=n;i=j)
{
x=0;
for(j=i;j<=n && a[b[i]]*a[b[j]]==0;j++)
if(a[b[j]]*a[b[j]-1]<=0 && a[b[j]]*a[b[j]+1]<0)
{
if((a[b[j]-1]-a[b[j]])*(a[b[j]+1]-a[b[j]])<0) t--;
else x--;
}
else if(a[b[j]]*a[b[j]-1]>0 && a[b[j]]*a[b[j]+1]>=0)
{
if((a[b[j]-1]-a[b[j]])*(a[b[j]+1]-a[b[j]])>0) t++;
else x++;
}
ans=max(ans,t);t+=x;ans=max(ans,t);
}
printf("%d\n",ans+1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息