给你n个药的序列,牛从时间1开始吃药,在奇数时间吃药可以增加弹跳力,在偶数时间吃药则会减少弹跳力。在某一时间,你可以跳过一些药,但一旦吃过某种药,你就不能在选前面的药了。问你某一个吃药的序列,使牛最终的弹跳力最大。
解法有多种,可以dp,可以贪心。
动态规划:
dp[i][0] 表示 当拿到第i个药时,之前已经拿了奇数个药的最大弹跳力。
dp[i][1] 表示 当拿到第i个药时,之前已经拿了偶数个药的最大弹跳力。
方程就是,
dp[i][0] = max(dp[i-1][0], dp[i-1][1]- v[i]);
dp[i][1] = max(dp[i-1][1], dp[i-1][0]+v[i]);
贪心解法:
把原序列分割成若干个小段,保证每个小段最大值在最小值之前,而每次吃药的时候就先吃最大值,再吃最小值,就能保证弹跳力在不断的增加。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int dp[151000][2];
int maxd(int a,int b)
{
return a<b?b:a;
}
int main()
{
int n,i,t;
while (scanf("%d",&n) != EOF)
{
dp[0][0]=0;
dp[0][1]=0;
for (i=1; i<=n; i++)
{
scanf("%d",&t);
dp[i][0]=maxd(dp[i-1][0],dp[i-1][1]-t);
dp[i][1]=maxd(dp[i-1][1],dp[i-1][0]+t);
}
printf("%d\n",maxd(dp[n][0],dp[n][1]));
}
}