1007. Maximum Subsequence Sum (25)

来源:互联网 发布:mac英英词典 编辑:程序博客网 时间:2024/06/06 02:46


1007. Maximum Subsequence Sum (25)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

Given a sequence of K integers { N1, N2, ..., NK }. A continuous subsequence is defined to be { Ni, Ni+1, ..., Nj } where 1 <= i <= j <= K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20.

Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.

Input Specification:

Each input file contains one test case. Each case occupies two lines. The first line contains a positive integer K (<= 10000). The second line contains K numbers, separated by a space.

Output Specification:

For each test case, output in one line the largest sum, together with the first and the last numbers of the maximum subsequence. The numbers must be separated by one space, but there must be no extra space at the end of a line. In case that the maximum subsequence is not unique, output the one with the smallest indices i and j (as shown by the sample case). If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.

Sample Input:
10-10 1 2 3 4 -5 -23 3 7 -21
Sample Output:
10 1 4

提交代码

解题思路:这是一个背包问题,每个数可以放进去也可以不放进去,如果没放之前就是负数则不放,如果是正数就放进去。后面再把最后一个数的 下标记录下来,依次从后往前推就可以了#include<iostream>  #include<string>  #include<cstring>  using namespace std;  int main(){  //freopen("input.txt","r",stdin);  int n;      while(scanf("%d",&n)!=EOF&&n){          int a[10000];//为了避免每次都使用memset初始化就直接放到里面定义           int dp[10000];          int flag=1;//作为判断是否所有数都小于0的标志           for(int i = 1;i<=n;i++){              scanf("%d",&a[i]);              if(a[i]>=0){                  flag=0;//至少存在一个不小于0的数               }          }          if(flag){//如果全是小于0的数,输出并且跳出               printf("0 %d %d\n",a[1],a[n]);              continue;          }          dp[0]=0;          int max=0;          int index = 0;          for(int i = 1;i<=n;i++){              if(dp[i-1]<0)              dp[i]=a[i];//如果前面子序列的和小于0,则该位置的最长连续子序列最大和就是自己               else              dp[i]=dp[i-1]+a[i];              if(dp[i]>max){//特别之处按题目要求输出最小的,所以这里是大于而不是大于等于                   max=dp[i];//找出子序列最大的和,把最后的下标记录下来                   index=i;              }          }          int start=0;          int end=index;          int sum=0;          for(int i = end;i>=0;i--){              sum+=a[i];//从结束位置往前加,刚好等于最大值就跳出               if(sum==max){                   start=i;                  break;              }          }          printf("%d %d %d\n",max,a[start],a[end]);      }      return 0;  }  


原创粉丝点击