线性/简单DP | 问题集合

牛跳问题DP解法
本文介绍了一道经典的动态规划问题——牛跳问题,并详细解析了如何通过动态规划求解牛的最大跳跃高度。通过设置状态f[i][j]来表示前i个药水中选择了奇偶性为j的个数的药的最大跳跃值。

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 }
牛跳

 


 

转载于:https://www.cnblogs.com/Yuns/p/7774507.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值