HUOJ-10857 最大的面积 凸包+DP
题目链接:http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=10857&courseid=55
比赛的时候把题目看成取恰好K个点了,,,悲剧。。然后按照正确的题意的话,是比较好做的,求个凸包,然后DP就可以了,f[i][j][k]表示第 i 个点到第 j 点选择k个点的多边形的最大面积,那么f[i][j][k]=Max{ f[i][j][k], f[i][y][k-1]+area(p[i],p[y],p[j]) }就可以了。。
这题相当悲剧,题目的数据范围描述错了,k应该是小于等于30,因为题目sb,看了一晚上的代码= =!
1 //STATUS:C++_AC_0MS_1284KB 2 #include <functional> 3 #include <algorithm> 4 #include <iostream> 5 //#include <ext/rope> 6 #include <fstream> 7 #include <sstream> 8 #include <iomanip> 9 #include <numeric> 10 #include <cstring> 11 #include <cassert> 12 #include <cstdio> 13 #include <string> 14 #include <vector> 15 #include <bitset> 16 #include <queue> 17 #include <stack> 18 #include <cmath> 19 #include <ctime> 20 #include <list> 21 #include <set> 22 #include <map> 23 using namespace std; 24 //#pragma comment(linker,"/STACK:102400000,102400000") 25 //using namespace __gnu_cxx; 26 //define 27 #define pii pair<int,int> 28 #define mem(a,b) memset(a,b,sizeof(a)) 29 #define lson l,mid,rt<<1 30 #define rson mid+1,r,rt<<1|1 31 #define PI acos(-1.0) 32 //typedef 33 typedef long long LL; 34 typedef unsigned long long ULL; 35 //const 36 const int N=60; 37 const int INF=0x3f3f3f3f; 38 const int MOD=1000000007,STA=8000010; 39 const LL LNF=1LL<<60; 40 const double EPS=1e-8; 41 const double OO=1e60; 42 const int dx[4]= {-1,0,1,0}; 43 const int dy[4]= {0,1,0,-1}; 44 const int day[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31}; 45 //Daily Use ... 46 //End 47 48 struct point{ 49 double x, y; 50 }p[N],res[N]; 51 52 double f[N][N]; 53 int T,n,k; 54 55 bool mult(point sp, point ep, point op) 56 { 57 return (sp.x - op.x) * (ep.y - op.y)>= (ep.x - op.x) * (sp.y - op.y); 58 } 59 60 bool operator < (const point &l, const point &r) 61 { 62 return l.y < r.y || (l.y == r.y && l.x < r.x); 63 } 64 65 int graham(point pnt[], int n, point res[]) 66 { 67 int i, len, k = 0, top = 1; 68 sort(pnt, pnt + n); 69 if (n == 0) return 0; 70 res[0] = pnt[0]; 71 if (n == 1) return 1; 72 res[1] = pnt[1]; 73 if (n == 2) return 2; 74 res[2] = pnt[2]; 75 for (i = 2; i < n; i++){ 76 while (top && mult(pnt[i], res[top], res[top-1]))top--; 77 res[++top] = pnt[i]; 78 } 79 len = top; 80 res[++top] = pnt[n - 2]; 81 for (i = n - 3; i >= 0; i--){ 82 while (top!=len && mult(pnt[i], res[top], res[top-1])) top--; 83 res[++top] = pnt[i]; 84 } 85 return top; // 返回凸包中点的个数 86 } 87 88 double arear(point& a,point& b,point& c) 89 { 90 double ret=0; 91 ret+=a.x*b.y-a.y*b.x; 92 ret+=b.x*c.y-b.y*c.x; 93 ret+=c.x*a.y-c.y*a.x; 94 return ret/2; 95 } 96 97 int main() 98 { 99 // freopen("in.txt","r",stdin); 100 int i,j,x,y,cnt; 101 double ans; 102 scanf("%d",&T); 103 while(T--) 104 { 105 scanf("%d%d",&n,&k); 106 for(i=0; i<n; i++){ 107 scanf("%lf%lf",&p[i].x,&p[i].y); 108 } 109 cnt=graham(p,n,res); 110 if(cnt<=2 || k<=2){ 111 printf("0.00\n"); 112 continue; 113 } 114 if(cnt<=k){ 115 double sum=0; 116 for(i=0;i<cnt;i++) 117 sum+=res[i].x*res[(i+1)%cnt].y-res[i].y*res[(i+1)%cnt].x; 118 printf("%.2lf\n",sum/=2); 119 continue; 120 } 121 ans=0; 122 int m=cnt; 123 while(m--){ 124 mem(f,0); 125 point t=res[0]; 126 for(j=0;j<cnt-1;j++)res[j]=res[j+1]; 127 res[j]=t; 128 for(j=2;j<cnt;j++){ 129 for(x=3;x<=j+1 && x<=k;x++){ 130 for(y=x-2;y<j;y++){ 131 f[j][x]=max(f[j][x],f[y][x-1]+arear(res[0],res[y],res[j])); 132 } 133 } 134 ans=max(ans,f[j][k]); 135 } 136 } 137 138 printf("%.2lf\n",ans); 139 } 140 return 0; 141 }