1. 程式人生 > >Super Jumping!Jumping!Jumping!(HDU_1087)(dp求最長上升子序列的和)

Super Jumping!Jumping!Jumping!(HDU_1087)(dp求最長上升子序列的和)

inf 自己 長度 int ans out clas urn class

傳送門:HDU_1087

題意:現在要玩一個跳棋類遊戲,有棋盤和棋子。從棋子st開始,跳到棋子en結束。跳動棋子的規則是下一個落腳的棋子的號碼必須要大於當前棋子的號碼。st的號是所有棋子中最小的,en的號是所有棋子中最大的。最終所得分數是所有經過的棋子的號碼的和。

思路:讀完題之後知道這是一個最長上升子序列的題目。因為之前剛剛看過牛客網上一節講解最長上升子序列的視屏,所以一上來就找準了方向,but我只知道怎麽求最長上升子序列的長度啊,和怎麽求???於是自己想方法開始求和,然後就wa掉了一個上午。下午起床後,搜了一下題解,看過思路後發現這種動規的做法,之前用到過,但是,,,,,,,,罪過罪過。

復雜度:O(n^2),對每一個棋子分配一個dp,每個棋子,遍歷他之前的棋子並從中找出dp[j]+a[i]最大的值賦給dp[i]。

代碼:

技術分享圖片
 1 #include <iostream>
 2 #include <queue>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <cstring>
 7 #define INF 0x3f3f3f3f
 8 
 9 using namespace std;
10 typedef long long ll;
11 const int maxn = 2010;
12 ll a[maxn],b[maxn],dp[maxn];
13 14 int main() 15 { 16 ios::sync_with_stdio(false); 17 int n; 18 while(cin>>n && n) 19 { 20 memset(a,0,sizeof(a)); 21 memset(dp,0,sizeof(dp)); 22 for(int i = 0; i<n; i++) 23 cin>>a[i]; 24 ll ans = -1e9; 25 for(int
i = 0; i<n; i++) 26 { 27 dp[i] = a[i]; 28 for(int j = 0; j<i; j++) 29 { 30 if(a[j]<a[i]) 31 { 32 dp[i] = max(dp[j]+a[i], dp[i]); 33 } 34 } 35 ans = max(ans,dp[i]); 36 } 37 cout<<ans<<endl; 38 } 39 return 0; 40 } 41 /* 42 樣例輸入: 43 3 1 3 2 44 4 1 2 3 4 45 4 3 3 2 1 46 0 47 樣例輸出: 48 4 49 10 50 3 51 */
View Code

Super Jumping!Jumping!Jumping!(HDU_1087)(dp求最長上升子序列的和)