暴力枚举凸多边形起点,dp[i][j][k]维护起点是i,终点是j,由k个点组成的凸多边形
转移方程:dp[i][j][p+1]=max(dp[i][j][p+1],dp[i][k][p]+s(i,k,j));
#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> using namespace std; #define maxn 205 int n,m; int x[maxn],y[maxn]; long long dp[maxn][maxn][maxn]; int s(int i,int j,int k){ return x[i]*y[j]+x[j]*y[k]+x[k]*y[i]-x[i]*y[k]-x[j]*y[i]-x[k]*y[j]; } int main() { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%d%d",&x[i],&y[i]); for(int i=0;i<n;i++) x[i+n]=x[i],y[i+n]=y[i]; memset(dp,-1,sizeof(dp)); for(int i=0;i<n;i++) dp[i][i][1]=0; long long ans=0; for(int i=0;i<n;i++) for(int j=i+1;j<i+n;j++) for(int p=0;p<m;p++) for(int k=i;k<j;k++) { if(dp[i][k][p]==-1) continue; dp[i][j][p+1]=max(dp[i][j][p+1],dp[i][k][p]+s(i,k,j)); if(p+1==m) ans=max(ans,dp[i][j][p+1]); } printf("%lld",ans/2); if(ans%2==1) printf(".50\n"); else printf(".00\n"); }