合并石子

Posted anyixing-fly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了合并石子相关的知识,希望对你有一定的参考价值。

技术图片

 

分析

  这道题题目已经很裸了,不需要题意解释,看数据范围发现n3的效率肯定过不了,四边形不等式的n2呢?求最大值,不能用,而某nlogn的算法,盒盒,看不懂,所以考虑一种别的办法。

引理

  合并区间(i,j)的石子时,最优断开位置k要么是i+1,要么是j-1。下面是证明(当然不是我写的啦,引用某大佬的证明)

技术图片

  于是我们可以得到,断开点一定是最左边的点或是最右边的点,引理得证。

  所以有状态转移方程

    技术图片

 

  然后就可以以n2的效率求解这道题了。

问题

  求解时i要倒序枚举,j要正序枚举,这里这么做是因为最佳划分点为i+1时,dpi由dpi+1转移,如果i正序枚举,就会用错误信息更新答案,不WA才怪,j也是同理

 

#include<iostream>
using namespace std;
const int N=4e3+1;
int s[N],dp[N][N];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>s[i];
        s[i+n]=s[i];
    }
    for(int i=1;i<n<<1;i++)
        s[i]+=s[i-1];
    for(int i=(n<<1)-1;i;i--)
        for(int j=i+1;j<=n<<1;j++)
            dp[i][j]=max(dp[i+1][j],dp[i][j-1])+s[j]-s[i-1];
    int ans=0;
    for(int i=1;i<=n;i++)
        ans=max(ans,dp[i][i+n-1]);
    cout<<ans;
}

  最近在学DP,代码都不难写,主要是状态转移方程不好推。。。。

   顺便再提一句,该做法好像只适用于求最大值,求最小值时有几率不对(很大几率),但给出证明的人说可以,但我明明举出了反例啊。。。。

  比如4 1 1 1 1这组,最小应该时8,从中间断开为分割点,但用上边方法的话会求出9;所以我们是不是可以求最大用这个,最小用四边形不等式呢(手动滑稽

以上是关于合并石子的主要内容,如果未能解决你的问题,请参考以下文章

石子合并问题

282. 石子合并

石子合并

石子合并

合并石子大总结

P5569 SDOI2008 石子合并(黑科技)