一本通OJ-P1571凸多边形的划分
题目
测试得分: 30
主要算法 : 动态规划,区间DP,高精类
题干:
区间DP板子题
应试策略:
- 确定状态//f[i][j]表示的i-j这一凸边形划分的最小值
- 枚举区间长度FORa(l,1,n)
- 枚举区间开头for(int i=1,in=2*n-l+1;i<=in;i++)
- 状态转移f[i][j]=min(f[i][j],f[i][k]+f[k][j]+a[i]*a[k]*a[j]);//注意,此时的边界因为是顶点是可以包含的
- 更新答案 if(l==n) ans=max(ans,f[i][i+n-1]);
#include<stdio.h> #include<stdlib.h> #define FORa(i,s,e) for(int i=s;i<=e;i++) #define FORs(i,s,e) for(int i=s;i>=e;i--) using namespace std; const int N=50,INF=1000000000; int a[N+1]; int n,ans=INF,f[N+1][N+1];//f[i][j]表示的i-j这一凸边形划分的最小值 inline int min(int fa,int fb){return fa<fb?fa:fb;} int main() { scanf("%d",&n); FORa(i,1,n) scanf("%d",&a[i]); FORa(l,1,n)//枚举区间长度 { for(int i=1,in=n-l+1;i<=in;i++)//枚举区间开头 { f[i][i+l]=INF; f[i][i+1]=0;//不能构成三角形 for(int k=i,j=i+l;k<j;k++) f[i][j]=min(f[i][j],f[i][k]+f[k][j]+a[i]*a[k]*a[j]);//注意,此时的边界因为是顶点是可以包含的 if(l==n) ans=min(ans,f[i][i+n-1]); } } printf("%d",ans); return 0; } /*5 121 122 123 245 231*/
总结:
- 初值
- 边界
- 状态转移