九度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 }