码迷,mamicode.com
首页 > 其他好文 > 详细

合并石子

时间:2020-03-28 13:39:39      阅读:60      评论:0      收藏:0      [点我收藏+]

标签:需要   倒序   错误   stream   dpi   答案   题目   using   信息   

技术图片

 

分析

  这道题题目已经很裸了,不需要题意解释,看数据范围发现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;所以我们是不是可以求最大用这个,最小用四边形不等式呢(手动滑稽

合并石子

标签:需要   倒序   错误   stream   dpi   答案   题目   using   信息   

原文地址:https://www.cnblogs.com/anyixing-fly/p/12586813.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!