poj 2385 Apple Catching(dp,状态转移)

题意:有两棵苹果树,编号为1,2,每分钟有一棵树会掉落一个苹果。一头牛在树下接苹果,每分钟只能站在一棵树下,但在树间转移的时间忽略不计。给定最大的转移次数w,问这只牛最多能接住多少苹果?”

题解:关键是寻找状态转移方程,取dp[i][j]的含义为:在i时刻,已经转移j次的情况下的接到的最大苹果数量,

则i时刻,已经转移j次的情况只能从两种状态转移过来

  1. i-1时刻已经转移j次的情况
  2. 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;
}

猜你喜欢

转载自blog.csdn.net/wwwlps/article/details/81407854