此题用简单dp解决,最长上升子序列和。
问题思考: 对某一个数,它是还是不是最大子序列和里的一位,我们设一个数组dp[],
dp[i]就表示以第i个数为最后一位的前1到i个数中的最长子序列的总和(注意这个最长是指以第i个数结尾的子序列中最长的)。
这样我们很快就能想到,要算dp[i+1]时,即要求出以第i+1个数为末位的前1到i+1个数中最长的子序列和。
就是拿第i+1个数与前面所有小于第i+1个数的值的dp数组的值相加,保存其中最大的一个就可以了。
因为对于dp[k] (k < i+1) 第k个数只要小于第i+1个数,那么也就意味着这个子序列可以更长更大。
可以看出根据这个算法,在所有元素都有序的情况下,时间复杂度最大。达到了O(n^2).
贴上码:
#include <string.h> #include <stdio.h> #define N 1001 int dp[N]; int main() { int T,j,i,max,t; int a[N]; while(scanf("%d",&T),T){ memset(a,0,sizeof(a)); for(i = 1; i <= T; i++){ scanf("%d",&a[i]); } memset(dp,0,sizeof(dp)); max = -1; for(i = 0; i <= T; i++){ t = 0; for(j = 0; j < i; j++){ if(a[i] > a[j]){ if( t < dp[j]) t = dp[j]; } } dp[i] = t + a[i]; if(dp[i] > max)max = dp[i]; } printf("%d\n",max); } return 0; }
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <map> #include <set> #include <vector> #include <stack> #include <algorithm> using namespace std; #define mst(a,b) memset(a,b,sizeof(a)) #define eps 10e-8 const int MAX_ = 1010; const int N = 100010; const int INF = 0x7fffffff; int a[MAX_], dp[MAX_]; int main(){ int n, cnt, k, res; while(scanf("%d",&n), n){ for(int i = 1; i <= n; ++i){ scanf("%d",&a[i]); } int ans = -INF; for(int i = 1; i <= n; ++i){ dp[i] = a[i]; for(int j = 1; j < i; ++j){ if(a[i] > a[j]){ dp[i] = max(dp[i], dp[j] + a[i]); } } ans = max(ans,dp[i]); } printf("%d\n",ans); } return 0; }