HDU1003Max Sum(original) HDU1024Max Sum Plus Plus(upgrading)

Max Sum

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


Problem Description
Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.
 

Input
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).
 

Output
For each test case, you should output two lines. The first line is "Case #:", # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.
 

Sample Input
 
  
2 5 6 -1 5 4 -7 7 0 6 -1 1 -6 7 -5
 
Sample Output
 
  
Case 1: 14 1 4 Case 2: 7 1 6


最简单版本的最大连续子序列和,无需多说,直接贪心。注意全是负数的情况即可。

#include<cstdio>
#include<algorithm>
#define INF 1<<30
using namespace std;
int a[100005];
int main(){
    int t,tc = 0, _t;
    scanf("%d",&t);
    _t = t - 1;
    while(t--){
        int n;
        scanf("%d",&n);
        if(t != _t)printf("\n");
        int tag = 0;
        int sum = 0, ans = 0, tmp = 0,l = 0,r = 0;
        int maxnum = -INF, index;
        for(int i = 0; i < n; i++){
            scanf("%d",a+i);
            if(a[i]>0)tag = 1;
            if(maxnum < a[i])maxnum = a[i], index = i;
            sum += a[i];
            if(sum < 0) sum = 0,tmp = i+1;
            if(ans < sum){
                l = tmp;
                r = i;
                ans = sum;
            }
        }
        if(!tag){
            printf("Case %d:\n%d %d %d\n",++tc, maxnum, index+1,index+1);
            continue;
        }
        printf("Case %d:\n%d %d %d\n",++tc,ans,l+1,r+1);
    }
    return 0;
}

Max Sum Plus Plus

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


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 S 1, S 2, S 3, S 4 ... S x, ... S n (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ S x ≤ 32767). We define a function sum(i, j) = S i + ... + S j (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(i 1, j 1) + sum(i 2, j 2) + sum(i 3, j 3) + ... + sum(i m, j m) maximal (i x ≤ i y ≤ j x or i x ≤ j y ≤ j x 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(i x, j x)(1 ≤ x ≤ m) instead. ^_^
 

Input
Each test case will begin with two integers m and n, followed by n integers S 1, S 2, S 3 ... S n.
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


升级版,题意大概可以表述成:要求将给定串分成若干不相交的部分,求各部分的max sum的最大和。

思路:动态规划。dp[ i ][ j ]表示前 j 个元素分成 i 段得到的最大和,则有状态转移方程dp[ i ][ j ]=max(dp[ i ][ j-1], dp[ i-1 ][ k ]) + a[ j ],k: i-1 ->  j-1,表示第 j 个元素的两种情况:加入前一个连续子串和自己重新成为一个串。那么题目大概就差不多了,注意优化成一维的形式(或者滚动数组),并且为了减小复杂度,要开一个数组记录i - 1行的dp值。

#include<cstdio>
const int maxn = 1000005, INF = 1<<30;
int pre[maxn], dp[maxn], a[maxn], maxnum,m ,n;
int main(){
    while(~scanf("%d %d",&m,&n)){
        for(int i = 1; i <= n; i++) scanf("%d",a+i),dp[i]=pre[i]=0;
        dp[0]=pre[0]=0;
        for(int i = 1; i <= m; i++){
            maxnum = -INF;
            for(int j = i; j <= n; j++){
                dp[j] = (dp[j-1]>pre[j-1]?dp[j-1]:pre[j-1])+a[j];
                pre[j-1] = maxnum;
                maxnum = maxnum>dp[j]?maxnum:dp[j];
            }
        }
        printf("%d\n",maxnum);
    }
    return 0;
}

 


猜你喜欢

转载自blog.csdn.net/Mad_boys/article/details/48167405
今日推荐