九度oj 1480

题目描述:                       

一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, ...,aN),我们可以得到一些上升的子序列(ai1, ai2, ..., aiK),这里1 <= i1 < i2 < ... < iK <= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中序列和最大为18,为子序列(1, 3, 5, 9)的和.

你的任务,就是对于给定的序列,求出最大上升子序列和。注意,最长的上升子序列的和不一定是最大的,比如序列(100, 1, 2, 3)的最大上升子序列和为100,而最长上升子序列为(1, 2, 3)。

输入:                       

输入包含多组测试数据。 每组测试数据由两行组成。第一行是序列的长度N (1 <= N <= 1000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000(可能重复)。

输出:                       

对于每组测试数据,输出其最大上升子序列和。

样例输入:                       
7
1 7 3 5 9 4 8
样例输出:                       
18

这道题本来不是什么难题,只需用一个sum[]来记录每一个位置的最大上升和,每回找前面一个比当前元素小且最大的sum[]相加求出当前位置的最大上升和。
但一开始我想当然的认为离的当前元素最近的小值即为所求元素,还用了一个数组来记录,导致问题过于复杂。
后来终于用最简单的办法做了出来,但要注意它这个是严格上升的子序列。
 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #define MAX 1005
 5 int sum[MAX];
 6 int num[MAX];
 7 //1 2 3 4 5 6 7
 8 //1 7 3 5 9 4 8
 9 //0 1 1 3 4 3 6
10 //1 8 4 9 18 7 15
11 //0 5 2 3 1 0 2 4 5 8
12 //5 4 8 2 5 7 5 6
13 
14 int main(int argc, char const *argv[])
15 {
16     int n;
17     while(scanf("%d",&n) != EOF) {
18         int max = 0;
19         for(int i = 1; i <= n; i++) {
20             scanf("%d",&num[i]);
21         }
22         sum[1] = num[1];
23         for(int i = 1; i <=n; i++) {
24             int maxTemp = num[i];
25             for(int j = i - 1; j >= 1; j--) {
26                 if(num[i] > num[j]) {
27                     int temp = sum[j] + num[i];
28                     if(maxTemp < temp) {
29                         maxTemp = temp;
30                     }
31                 }
32             }
33             sum[i] = maxTemp;
34             if(max < maxTemp) {
35                 max = maxTemp;
36             }
37             
38         }
39         /*for(int i = 1; i <= n; i++) {
40             printf("%d\t",sum[i]);
41         }*/
42         printf("%d\n", max);
43     }
44     //system("pause");
45     return 0;
46 }

 



posted @ 2016-07-15 19:31  Jason杰  阅读(442)  评论(0编辑  收藏  举报