题意:有两棵苹果树,编号为1,2,每分钟有一棵树会掉落一个苹果。一头牛在树下接苹果,每分钟只能站在一棵树下,但在树间转移的时间忽略不计。给定最大的转移次数w,问这只牛最多能接住多少苹果?”
题解:关键是寻找状态转移方程,取dp[i][j]的含义为:在i时刻,已经转移j次的情况下的接到的最大苹果数量,
则i时刻,已经转移j次的情况只能从两种状态转移过来
- i-1时刻已经转移j次的情况
- i-1时刻已经转移j-1次的情况
我一开始得出dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+1,然后发现这样是错误的,在i时刻,已经转移j次的情况下,不一定能接到这个
时刻的苹果,这还和转移次数j有关系,如果转移的是偶数次,就停留在第一棵树下,否则在第二棵树下面
正确的解法是:
dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]);
if(j%2+1==a[i])
dp[i][j]++;
还有,在0时刻,苹果没有掉落,dp[0][j]都为0
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1005
using namespace std;
int n;
int dp[maxn][35];
int t[maxn],a[maxn],times,cnt;
void solve()
{
memset(dp,0,sizeof(dp));//0时刻,苹果没有掉落,无论转移多少次都是0
for(int i=1;i<=n;i++)
{
for(int j=0;j<=times;j++)
{
if(j==0)
dp[i][j]=dp[i-1][j];
else
dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]);
if(j%2+1==a[i])
dp[i][j]++;
}
}
int maxi=-1;
for(int i=0;i<=times;i++)
{
if(maxi<dp[n][i])
maxi=dp[n][i];
}
cout << maxi << endl;
}
int main()
{
cin>>n>>times;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
solve();
return 0;
}