题意:
很久很久以前,山上有两棵苹果树,每一分钟,其中一棵就会掉下一颗苹果。
树下有一只牛,好吃懒做。
每一分钟只可以出现在某一棵苹果树下面,因为他没有买分身斧,dotaer都懂的。
问给定一个奔跑次数,怎样奔跑才能吃到的苹果数量最多。
思路:
dp。
申请一个二维数组dp [ j ] [ w ] 。j 代表此状态下 剩余奔跑速度 j 的条件下 ,站在w树下的最大吃到苹果树 ( w=0或者1)。
其实本来是三维dp [ i ][ j ][ w ],i代表在第 i 分钟,但是因为 i 状态下只跟 i -1 状态有关,可以进行空间优化。
w是读取的此分钟时,哪棵树掉苹果。
状态转移方程如下:
dp[j][w]=Max(dp[j+1][1-w],dp[j][w])+1;
dp[j][1-w]=dp[j][1-w];
最后要注意的是看一下discuss,牛刚开始其实是站在哪棵树下都可以。
#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<cmath>
#include<algorithm>
#define llong long long
#define Min(a,b) (a<b?a:b)
#define Max(a,b) (a>b?a:b)
#define Abs(a) ((a)>0?(a):-(a))
#define Mod(a,b) (((a)-1+(b))%(b)+1)
using namespace std;
int n,m;
const int N=1005;
const int M=35;
const int inf=99999999;
int dp[M][2];
int main()
{
int w;
scanf("%d%d",&n,&m);
for(int j=0;j<=m;j++)
{
dp[j][1]=-inf;
dp[j][0]=-inf;
}
dp[m][0]=dp[m][1]=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&w);
w--;
for(int j=0;j<=m;j++)
{
dp[j][w]=Max(dp[j+1][1-w],dp[j][w])+1;
dp[j][1-w]=dp[j][1-w];
}
}
int ans=0;
for(int i=0;i<=m;i++)
{
ans=Max(ans,dp[i][0]);
ans=Max(ans,dp[i][1]);
}
printf("%d\n",ans);
return 0;
}