1068. 环形石子合并 (环形,区间dp)

原题链接- AcWing 

分析:与石子合并只加了一个环形的条件

对于环形问题,如果只是枚举中断点的话,在石子合并的基础上多开一维,时间复杂度是O(n^4)

可以采用一个普遍的方法,就是把环转换成一个链

 

 通过把从1展开的链接在n的后面,这样子枚举的时候枚举以 位置2 断开的链,只需要枚举 以2开始,长度为len的链,就可以枚举n与1相邻的情况了

状态转移方程基本和石子合并一样,不同点在于环的存在,导致循环枚举不同

for(int len=1;len<=n;len++)
        for(int l=1;l+len-1<=2*n;l++)
        {//由于模拟中间断点,把前面断开的接到数组后面去,所以最大可能枚举到2n

           ...
        }

 

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=410;
int a[N];
int s[N];
int dp[N][N];
int g[N][N];

int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i],a[n+i]=a[i];
    
    for(int i=1;i<=2*n;i++) s[i]=s[i-1]+a[i];
    
    memset(dp,0x3f,sizeof dp),memset(g,-0x3f,sizeof g);
    
    for(int len=1;len<=n;len++)
        for(int l=1;l+len-1<=2*n;l++)
        {
            int r=l+len-1;
            if(len==1) dp[l][r]=g[l][r]=0;
            else
                for(int k=l;k<r;k++)
                {
                    dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]+s[r]-s[l-1]);
                    g[l][r]=max(g[l][r],g[l][k]+g[k+1][r]+s[r]-s[l-1]);
                }
        }
    int maxv=-0x3f3f3f3f,minv=0x3f3f3f3f;
    for(int i=1;i<=n;i++)
        minv=min(minv,dp[i][i+n-1]),maxv=max(maxv,g[i][i+n-1]);
    cout<<minv<<endl<<maxv<<endl;
    return 0;
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值