0
点赞
收藏
分享

微信扫一扫

【区间DP】石子合并

题目

 282. 石子合并 - AcWing题库

 AcWing 282. 石子合并(区间 DP 模版题详解分析) - AcWing

解释

  • 状态表示:f(i,j)表示将i到j合并成一堆的方案的集合,属性为min
  • 状态计算:i<j时,f(i,j)=min(f(i,k)+f(k+1,j)+s[j]-s[i-1]  i=j时,f(i,i)=0
  • 循环的第一层都为枚举区间长度,第二维是固定i的位置,确保每个状态都被计算到
  • 最后答案即(1~n)的总区间,即f(1,n)

代码段

区间DP模板

for (int i = 1; i <= n; i++) {
    dp[i][i] = 初始值
}
for (int len = 2; len <= n; len++)           //区间长度
    for (int i = 1; i + len - 1 <= n; i++) { //枚举起点
        int j = i + len - 1;                 //区间终点
        for (int k = i; k < j; k++) {        //枚举分割点,构造状态转移方程
            dp[i][j] = max(dp[i][j], dp[i][k] + dp[k + 1][j] + w[i][j]);
        }
    }

#include<iostream>
using namespace std;
const int N=310;
int a[N],s[N],f[N][N],n;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        s[i]=a[i]+s[i-1];
    }
    for(int i=1;i<=n;i++)
    f[i][i]=0;
    for(int len=2;len<=n;len++)
    for(int i=1;i+len-1<=n;i++)
    {
        int j=i+len-1;
        f[i][j]=1e9;
        for(int k=i;k<j;k++)
        {
            f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+s[j]-s[i-1]);
        }
    }
    cout<<f[1][n]<<endl;
    
}
举报

相关推荐

0 条评论