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 }

 

你可能感兴趣的:(dp)