传送门: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 */