1719: [Usaco2006 Jan] Roping the Field 麦田巨画
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 82 Solved: 26
[Submit][Status][Discuss]
Description
Farmer John is quite the nature artist: he often constructs large works of art on his farm. Today, FJ wants to construct a giant "field web". FJ‘s field is large convex polygon with fences along the boundary and fence posts at each of the N corners (1 <= N <= 150). To construct his field web, FJ wants to run as many ropes as possible in straight lines between pairs of non-adjacent fence posts such that no two ropes cross. There is one complication: FJ‘s field is not completely usable. Some evil aliens have created a total of G (0 <= G <= 100) grain circles in the field, all of radius R (1 <= R <= 100,000). FJ is afraid to upset the aliens, and therefore doesn‘t want the ropes to pass through, or even touch the very edge of a grain circle. Note that although the centers of all the circles are contained within the field, a wide radius may make it extend outside of the field, and both fences and fence posts may be within a grain circle. Given the locations of the fence posts and the centers of the circles, determine the maximum number of ropes that FJ can use to create his field web. FJ‘s fence posts and the circle centers all have integer coordinates X and Y each of which is in the range 0..1,000,000.
Input
* Line 1: Three space-separated integers: N, G, and R * Lines 2..N+1: Each line contains two space-separated integers that are the X,Y position of a fence post on the boundary of FJ‘s field. * Lines N+2..N+G+1: Each line contains two space-separated integers that are the X,Y position of a circle‘s center inside FJ‘s field.
Output
* Line 1: A single integer that is the largest number of ropes FJ can use for his artistic creation.
Sample Input
6 10
10 7
9 1
2 0
0 3
2 2
5 6
8 3
INPUT DETAILS:
A pentagonal field, in which all possible ropes are blocked by three
grain circles, except for the rope between fenceposts 2 and 4.
Sample Output
HINT
除了篱笆桩2和4之间可以连接绳索,其余均会经过怪圈
题目链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=1719
Solution
首先看到题目应该是几何题无误(假装很有道理
看到n<=150感觉似乎暴力也能过。。想想边数最多也只有22500条。。。
于是这时候应该马上想到先预处理每条边是否可以连。。。
直接算圆和线段的交点?感觉应该可以但是似乎不怎么好写。。。
考虑题意。。只要线段有部分含于圆内就不能连。。而这个“部分”可以直接认为是线段上与圆心最近的点。。
于是这个预处理就转化成了求点到线段的最小距离。。这个套套公式就好。。感觉三分也可以但是tle了(可能是我写炸了。。
预处理完之后,考虑怎么求答案。。。
要求线段之间不可以相交。。。。
说白了就是不能有1->4 , 2->5这样的线段同时存在。。考虑DP。。那肯定只能区间DP了。。
n<=150的话O(n^3)还是很轻松的吧
代码
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> #include<queue> #include<vector> #include<map> #define N 20050 #define ept 1e-6 using namespace std; int n,m; double R; struct P{ double x,y; }a[200],b[200]; int f[200][200]; bool vis[200][200]; double dis(P u,P v){ return sqrt((u.x-v.x)*(u.x-v.x)+(u.y-v.y)*(u.y-v.y)); } double DIS(P u,P v,P w) { double space=0; double a,b,c; a=dis(u,v); b=dis(u,w); c=dis(v,w); if(c<=ept||b<=ept) { space=0; return space; } if(a<=ept){ space=b; return space; } if(c*c>=a*a+b*b){ space=b; return space; } if(b*b>=a*a+c*c) { space=c; return space; } double p=(a+b+c)/2; double s=sqrt(p*(p-a)*(p-b)*(p-c)); space=2*s/a; return space; } bool judge(P u,P v,P w){ double d1=DIS(u,v,w); if(d1>R) return 0; return 1; } bool check(P u,P v){ for(int i=1;i<=m;i++) if(judge(u,v,b[i])) return 0; return 1; } int main(){ scanf("%d%d%lf",&n,&m,&R); for(int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y); for(int i=1;i<=m;i++) scanf("%lf%lf",&b[i].x,&b[i].y); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i==j) continue; vis[i][j]=check(a[i],a[j]); } } for(int len=3;len<=n;len++){ for(int i=1;i<=n-len+1;i++){ for(int j=i;j<=i+len-1;j++) f[i][i+len-1]=max(f[i][i+len-1],f[i][j]+f[j][i+len-1]); if(vis[i][i+len-1]&&(i!=1||i+len-1!=n)) f[i][i+len-1]++; } } printf("%d\n",f[1][n]); return 0; }
This passage is made by Iscream-2001.