hdu 6603 Azshara’s deep sea

2019 多校第三场A , 简单计算几何+简单dp

明明n<=400还10组数据,出题人硬说凸包上的点不会很多n^3可过,害我想一整场怎么优化。

题意:n个平面上的木桩,你要选出尽可能多的以凸包上两个不相邻木桩为顶点的线,使这些线互不相交而且不能与给定的g个圆相交。

把与圆相交的线去掉,然后做一个简单的区间dp即可。

  1. /*
  2. Author: fffasttime
  3. Date:
  4.  */
  5. #include <bits/stdc++.h>
  6. using namespace std;
  7. typedef long long ll;
  8. #define inc(i,n) for (int i=0;i<n;i++)
  9. const int N=100010;
  10.  
  11. typedef double db;
  12. const db eps=1e-9;
  13. bool eq(db x){return fabs(x)<eps;}
  14.  
  15. #define Vec const vec &
  16. #define Point const point &
  17. struct vec{
  18. 	db x,y;
  19. 	vec operator+(Vec v)const{return {x+v.x,y+v.y};}
  20. 	vec operator-(Vec v)const{return {x-v.x,y-v.y};}
  21. 	vec operator*(db t)const{return {x*t,y*t};}
  22. 	vec operator/(db t)const{return {x/t,y/t};}
  23.  
  24. 	db operator|(Vec v)const{return x*v.x+y*v.y;}
  25. 	db operator&(Vec v)const{return x*v.y-y*v.x;}
  26. 	db operator!()const{return sqrt(x*x+y*y);}
  27. 	bool operator<(vec v)const{
  28. 		return eq(x-v.x)?y<v.y:x<v.x;
  29. 	}
  30. 	void rd(){
  31. 		scanf("%lf%lf",&x,&y);
  32. 	}
  33. 	void prt(){printf("%f %f\n",x,y);}
  34. };
  35. typedef vec point;
  36. db cross(Vec a, Vec b, Vec c){return b-a&c-a;}
  37.  
  38. int convex(point *p, int n, point *ans){
  39. 	sort(p,p+n);
  40. 	int m=0;
  41. 	for (int i=0;i<n;i++){
  42. 		while (m>1 && cross(ans[m-2],ans[m-1],p[i])<=0) m--;
  43. 		ans[m++]=p[i];
  44. 	}
  45. 	int k=m;
  46. 	for (int i=n-2;i>=0;i--){
  47. 		while (m>k && cross(ans[m-2],ans[m-1],p[i])<=0) m--;
  48. 		ans[m++]=p[i];
  49. 	}
  50. 	if (n>1) m--;
  51. 	return m;
  52. }
  53.  
  54. db linedis(Vec p, Vec a, Vec b){
  55. 	vec v1=b-a, v2=p-a;
  56. 	return fabs(v1&v2/!v1);
  57. }
  58.  
  59. point p0[500],p[500],gr[110];
  60.  
  61. bool a[500][500];
  62. int dp[500][500];
  63.  
  64. int main(){
  65. 	int T; scanf("%d",&T);
  66. 	while (T--){
  67. 		int n,g,r;
  68. 		scanf("%d%d%d",&n,&g,&r);
  69. 		inc(i,n) p0[i].rd();
  70. 		inc(i,g) gr[i].rd();
  71. 		n=convex(p0,n,p);
  72. 		if (n<4){
  73. 			puts("0");
  74. 			continue;
  75. 		} 
  76. 		//for (int i=0;i<n;i++) p[i].prt();
  77. 		memset(a,0,sizeof a);
  78. 		for (int i=0;i<n;i++)
  79. 			for (int j=i+1;j<n;j++){
  80. 				for (int k=0;k<g;k++)
  81. 					if (linedis(gr[k],p[i],p[j])<=r)
  82. 						goto fail;
  83. 				a[i][j]=a[j][i]=1;
  84. fail:;
  85. 			}
  86. 		memset(dp,0,sizeof dp);
  87. 		for (int i=0;i<n;i++) a[i][(i+1)%n]=a[i][(i-1+n)%n]=0;
  88. 		for (int k=2;k<n;k++)
  89. 			for (int i=0;i+k<n;i++){
  90. 				for (int j=i+1;j<i+k;j++){
  91. 					dp[i][i+k]=max(dp[i][i+k],dp[i][j]+dp[j][i+k]+a[i][i+k]);
  92. 				}
  93. 			}
  94. 		//for (int i=0;i<n;i++,puts(""))
  95. 		//	for (int j=0;j<n;j++) cout<<a[i][j]<<' ';
  96. 		cout<<dp[0][n-1]<<'\n';
  97. 	}
  98. 	return 0;
  99. }

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注