zoukankan      html  css  js  c++  java
  • 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
    ");
    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
    ",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
    ",ans);
    139     }
    140     return 0;
    141 }
  • 相关阅读:
    assert()函数用法总结
    UnityiOS键盘无法输入Emoji
    Unity 字体相关
    设计模式相关
    Unicode 与字符编码
    Unity 优化相关小结
    dedecms二次开发技巧汇总
    公司绝对不会告诉你的20个潜规则
    Ubuntu 如何自定义快捷键截图选定区域
    从一份简历就可以判断应聘者
  • 原文地址:https://www.cnblogs.com/zhsl/p/3309065.html
Copyright © 2011-2022 走看看