杭电1024(Max Sum Plus Plus)

来源:互联网 发布:python 获取本机ip 编辑:程序博客网 时间:2024/05/03 18:47

点击打开杭电1024

Problem Description

Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To be a brave ACMer, we always challenge ourselves to more difficult problems. Now you are faced with a more difficult problem.

Given a consecutive number sequence S1, S2, S3, S4 ... Sx, ... Sn (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ Sx ≤ 32767). We define a function sum(i, j) = Si + ... + Sj (1 ≤ i ≤ j ≤ n).

Now given an integer m (m > 0), your task is to find m pairs of i and j which make sum(i1, j1) + sum(i2, j2) + sum(i3, j3) + ... + sum(im, jm) maximal (ix ≤ iy ≤ jx or ix ≤ jy ≤ jx is not allowed).

But I`m lazy, I don't want to write a special-judge module, so you don't have to output m pairs of i and j, just output the maximal summation of sum(ix, jx)(1 ≤ x ≤ m) instead. ^_^
 


Input

Each test case will begin with two integers m and n, followed by n integers S1, S2, S3 ... Sn.
Process to the end of file.
 

Output

Output the maximal summation described above in one line.
 

Sample Input

1 3 1 2 32 6 -1 4 -2 3 -2 3
 

Sample Output

68

思路:

          经典的动态规划优化的问题:设f(i, j)表示前i个数划分成j段,且包括第i个数的最大m子段和,那么有dp方程: 
f(i, j) = max { f(i - 1, j) + v[i], max {f(k, j - 1) + v[i]}(k = j - 1 ... i - 1) } 。可以引入一个辅助数组来优化转移。设g(i, j)表示前i个数划分成j段的最大子段和(注意第i个数未必在j段里面),那么递推关系如下: g(i, j) = max{g(i - 1, j), f(i, j)},  分是否加入第i个数来转移 这样f的递推关系就变成: f(i, j) = max{f(i - 1, j), g(i - 1, j - 1)} + v[i],这样最后的结果就是g[n][m],通过引入辅助数组巧妙的优化了转移。实现的时候可以用一维数组,速度很快 g[i][j]要么和g[i-1][j]相等,要么和f[i][j]相等 ,f[i][j]-a[i]要么和g[i-1][j-1]相等,要么和f[i-1][j]相等 。转成一维数组 到第i行时:f[j]=max{ f[j],g[j-1] }+a[i] } g[j]=max{ g[j],f[j] }。


代码实现:

import java.util.*;class Main{    public static void main(String[] args){        int j;        Scanner sc=new Scanner(System.in);        while(sc.hasNext()){            int m=sc.nextInt();int n=sc.nextInt();            int[] a=new int[n+1];int[] dp=new int[m+1];int[] dp2=new int[m+1];            for(int i=1;i<=n;i++){                a[i]=sc.nextInt();            }            dp[1]=a[1];dp2[1]=a[1];            for(int i=2;i<=n;i++){                for(j=1;j<=Math.min(i, m);j++){                    dp2[j]=Math.max(dp2[j]+a[i], dp[j-1]+a[i]);                    dp[j-1]=Math.max(dp[j-1], dp2[j-1]);                }                dp[j-1]=Math.max(dp[j-1], dp2[j-1]);            }            System.out.println(dp[m]);        }    }}




0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机丢了查话费欠了几百块怎么办 注销电信手机卡里面的余额怎么办 联通手机卡注销后里面的余额怎么办 手机卡网上销户以后剩余话费怎么办 联通新号注册微信发不了短信怎么办 韩博士装机卡在驱动恢复怎么办 xp打印后程序服务没有运行怎么办 刚注册的微信显示异常怎么办 不小心删了照片怎么办不要钱 qq邀请好友辅助验证成功后怎么办 微信申诉怎么让好友发验证码怎么办 微信申诉好友都删除了怎么办 恋与制作人原来的帐号不见了怎么办 手机号被别人注册了手机银行怎么办 想上老婆的陌陌号但要验证码怎么办 中国家医居民端注册信息有误怎么办 别人给我充的q币怎么办 qq忘记密码手机号码也换了怎么办 手机号码不用了微信忘记密码怎么办 手机号码注销了微信忘记密码怎么办 微信忘记密码手机号码也换了怎么办 微信钱包里的钱莫名少了怎么办 被骗给人冲q币了怎么办 支付宝账户异常无法领取红包怎么办 微信q币支付错了怎么办 王者荣耀不小心把点卷用了怎么办 微信绑定的qq号密码忘记了怎么办 微信红包实名认证没银行卡怎么办 手机烂了换新手机微信支付宝怎么办 支付宝转账给别人号码没用了怎么办 微信转账验证码收不到怎么办 陌生网友生日叫我发红包怎么办 微信群的群主不小心推出群该怎么办 支付宝验证码被别人知道了怎么办 微信解除银行卡绑定零钱清零怎么办 qq号被盗了理财通的钱怎么办 工行转错账号的钱被冻结怎么办 微信20w限额满了怎么办 通过qq号申请微信被盗了怎么办 微信号被盗手机绑定被改怎么办 腾讯视频激活码兑换达到限制怎么办