Acwing 320.能量项链【区间DP(环拆链)】

1.题目
题目链接:点这儿!
2.解决方法
区间DP是有固定模板的DP类型,它解决的问题都有合并区间(或理解为序列元素)求最优耗费这种模式,而且往往给定的是一个序列,像一个链条一样。但是如果链条的首尾串起来,变成环,该怎么运用区间DP的套路?可以将给定序列复制一倍放在序列的后面,这样做来模拟在环上操作。这样我们得到的最优解需要从通过状态转移方程计算出的f(1,n),f(2,n+1),…,f(i,n+i-1)中寻找。
3.代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long LL;
const int MAXN=110;

int n,s[2*MAXN];
int f[2*MAXN][2*MAXN];

int main(void)
{
    cin>>n;
    
    //环拆为链:复制链的一倍到链的后面,模拟环
    for(int i=1;i<=n;i++){
        cin>>s[i];
        s[n+i]=s[i];//复制到(n+1,2n)空间中
    }
    
    for(int len=2;len<=n;len++)//区间DP模板
        for(int l=1;l+len-1<=2*n;l++){
            int r=l+len-1;
            for(int k=l;k<r;k++)
                f[l][r]=max(f[l][r],f[l][k]+f[k+1][r]+s[l]*s[k+1]*s[r+1]);
        }
        
    int ans=0;
    
    for(int i=1;i<=n;i++)//选取f(1,n),f(2,n+1),...,f(i,n+i-1)中的最大值
        ans=max(ans,f[i][n+i-1]);
        
    cout<<ans<<endl;
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值