zoukankan      html  css  js  c++  java
  • HDU 1024:Max Sum Plus Plus(DP,最大m子段和)

                                      Max Sum Plus Plus

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 36673    Accepted Submission(s): 13069

    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 3

    2 6 -1 4 -2 3 -2 3

    Sample Output

    6

    8

    Hint

    Huge input, scanf and dynamic programming is recommended.

    题意

    给出一个长度为n的数组,求数组中m个不相交的子段的最大和


    参考了kuangbin大神的博客还有好多大佬们的博客才算勉强弄懂了。

    状态转移方程为:dp[i][j]=max(dp[i][j-1]+a[j],dp[i-1][k]+a[j])  i-1<=k<=j-1

    但是需要对这个方程进行优化,具体优化过程看下面各位大佬们的博客吧

    传送门

    kuangbin

    https://www.cnblogs.com/jiangjing/archive/2013/07/25/3214729.html

    https://blog.csdn.net/u013187393/article/details/42914165

    代码

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <math.h>
    #include <limits.h>
    #include <map>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <set>
    #include <string>
    #define ll long long
    #define ms(a) memset(a,0,sizeof(a))
    #define pi acos(-1.0)
    #define INF 0x3f3f3f3f
    const double E=exp(1);
    const int maxn=1e6+10;
    using namespace std;
    int a[maxn];
    int dp[maxn];//dp[j]表示到第j个时候的最大和
    int sum[maxn];//记录上个状态的j-1个前的最大值
    int main(int argc, char const *argv[])
    {
    	ios::sync_with_stdio(false);
    	int k,n;
    	while(cin>>k>>n)
    	{
    		ms(a);
    		ms(dp);
    		ms(sum);
    		for(int i=1;i<=n;i++)
    			cin>>a[i];
    		int ans;
    		for(int i=1;i<=k;i++)
    		{
    			ans=INT_MIN;
    			for(int j=i;j<=n;j++)
    			{
    				//当前位置的最大和
    				dp[j]=max(dp[j-1]+a[j],sum[j-1]+a[j]);
    				//记录上个状态的最大和
    				sum[j-1]=ans;
    				ans=max(ans,dp[j]);
    			}
    		}
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    Resize a VMWare disk (zz)
    StepbyStep: Installing SQL Server Management Studio2008 Express after Visual Studio 2010(zz)
    (C#)利用反射动态调用类成员[转载]
    Discuz!NT 系统架构分析 (转)
    C#反射实例讲解(转)
    什么是反射?
    创建保存图片目录
    取资源文件中的值 System.Resources.ResourceManager
    Net中的反射使用入门
    iis上实现虚拟目录
  • 原文地址:https://www.cnblogs.com/Friends-A/p/10324421.html
Copyright © 2011-2022 走看看