一本通OJ-P1571凸多边形的划分

题目

题目链接

测试得分:  30

主要算法 :  动态规划,区间DP,高精类

题干:

    区间DP板子题

应试策略:

  1. 确定状态//f[i][j]表示的i-j这一凸边形划分的最小值 
  2. 枚举区间长度FORa(l,1,n)
  3. 枚举区间开头for(int i=1,in=2*n-l+1;i<=in;i++)
  4. 状态转移f[i][j]=min(f[i][j],f[i][k]+f[k][j]+a[i]*a[k]*a[j]);//注意,此时的边界因为是顶点是可以包含的 
  5. 更新答案 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*/

总结:

  •   初值
  •   边界
  •   状态转移

原文地址:https://www.cnblogs.com/SeanOcean/p/11303734.html