PAT T1023 The Best Polygon
先对所有点极角排序,再动态规划~
#include<bits/stdc++.h> using namespace std; const int maxn=1014; struct node { double x,y,dx,dy; int id; }Node[maxn]; double dp[400][400][20],x=0,y=0; bool cmp (node a,node b) { return (a.x-x)*(b.y-y)<(a.y-y)*(b.x-x); } vector<int> ans,path[305][305]; double getArea (node a,node b,node c) { double x1=b.x-a.x; double y1=b.y-a.y; double x2=b.x-c.x; double y2=b.y-c.y; return abs(x1*y2-x2*y1)*0.5; } int main () { int n,m; scanf ("%d %d",&n,&m); for (int i=0;i<n;i++) { scanf ("%lf %lf",&Node[i].x,&Node[i].y); Node[i].id=i; x+=Node[i].x; y+=Node[i].y; } x/=n; y/=n; sort (Node,Node+n,cmp);//极角排序,让给出的点按顺时针排序 double Max=0; int ri,rj; for (int k=3;k<=m;k++) { for (int i=0;i<n;i++) { for (int j=n-1;j>=i+k-1;j--) { for (int l=j-1;l>=i+1;l--) { //dp[i][j][k]表示第i到第j个点选取k个点的最大值 double area=dp[i][l][k-1]+getArea(Node[i],Node[l],Node[j]); //中间结点第i个点到第l个点,选取k-1个点,再加上一个新选取的三角形 if (area>dp[i][j][k]) { dp[i][j][k]=area; path[i][j]=path[i][l]; path[i][j].push_back(l); //保存每个区间的路径 if (dp[i][j][k]>Max) { Max=dp[i][j][k];//保存当前k边形的最大值 ri=i; rj=j; } } } } } } ans.push_back(Node[ri].id); ans.push_back(Node[rj].id);//将两个端点推入数组 for (int i=0;i<path[ri][rj].size();i++) ans.push_back(Node[path[ri][rj][i]].id); sort (ans.begin(),ans.end()); for (int i=ans.size()-1;i>=0;i--) { if (i!=ans.size()-1) printf (" "); printf ("%d",ans[i]); } return 0; }