DP真的难.
简单DP一点也不简单DP
我TM就是个DP短板选手..
靠??今天的简单DP我居然打对了?
靠??看来我的DP有救了???
然后重点是Cys好菜菜菜菜菜菜啊!!!!
QZOJ1888.牛跳
题目描述
John的奶牛们计划要跳到月亮上去。它们请魔法师配制了P(1 <= P <=150,000)种药水,这些药水必需安原来的先后次序使用,但中间可以跳过一些药水不吃。每种药水有一个“强度”值 s ( 1 <= s <= 500 ),表示可以增强牛的跳跃能力。然而,药力的作用却是交替相反方向起作用,也就是说:当第奇数次吃药时,牛获得跳的更高的能力,而第偶数吃药时,却降低了跳高能力。在吃药前,牛的跳高能力当然为 0 。
每种药只能吃一次,开始时为第1次吃药。
请求出牛可能跳到的最高高度--最大跳跃能力。
输入格式
第一行:一个整数 P
下面P行:每行一个整数,表示按先后次序要吃的药水的“强度”。
输出格式
只一个整数,表示最大弹跳能力。
样例输入
8 7 2 1 8 4 3 5 6
样例输出e
17
解题思路
-
- 设f[i][j]表示前i个药水中选择了奇偶性为j的个数的药的最大跳跃值。 0和1分别表示偶数和奇数
- 则我们对于第i个药水的决策,有选/不选两个决策
- 若我们选择了这个药水i,则对于前i个药水,我们的奇偶性不同,若不选,则对于前i个药水奇偶性相同
- 首先我们先处理边界条件:
- f[1][0] = 0 //不选择第一个药水
- f[1][1] = a[1] //选择第一个药水
- 另我们对于当前第i个药水的决策有:
- 偶数选: f[i][0] = f[i-1][1]-a[i] //i-1次为1(奇数),则需要减去a[i]
- 奇数选: f[i][1] = f[i-1][0]+a[i] //i-1次为0(偶数),则可以加上a[i]
- 最后只需要取选/不选的最大值存入即可(如图
- = Copy之前题解,然鹅发现有很多不对劲的地方...
关于代码


1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 #define LL long long 7 using namespace std; 8 9 int Read() { 10 int val = 0, opt = 1; 11 char ch; 12 while (!(isdigit( ch = getchar() ) || ch == '-')); 13 if (ch == '-') opt =-1; 14 else val = ch - '0'; 15 while (isdigit( ch = getchar() )) (val *= 10) += ch - '0'; 16 return val * opt; 17 } 18 19 int Ans[150001][3]; 20 int Que[150001]; 21 22 int main(){ 23 24 ios :: sync_with_stdio(0); 25 26 int N; 27 cin >> N; 28 for (int i = 1 ; i <= N ; ++i) Que[i] = Read(); 29 30 Ans[1][1] = Que[1]; //奇数次吃 31 Ans[1][2] = 0; //偶数次吃 32 33 for (int i = 2 ; i <= N ; ++i){ 34 35 Ans[i][1] = max(Ans[i-1][2]+Que[i] , Ans[i-1][1]); 36 Ans[i][2] = max(Ans[i-1][1]-Que[i] , Ans[i-1][2]); 37 38 } 39 40 cout << max(Ans[N][1] , Ans[N][2]); 41 42 return 0; 43 }