POJ 2385 Apple Catching(动态规划)

问题:Apple CatchingPOJ - 2385

Description奶牛爱吃苹果是鲜为人知的事实。FJ在他的田地里有两棵苹果树(编号为1和2)。Bessie不会爬树,所以她必须等着苹果掉下来。然而,她必须在空中接住它们,因为苹果落地时碰伤了(谁也不想吃碰伤了的苹果)。Bessie吃得很快,吃的时间可以忽略不计。 每分钟,两棵苹果树中的一棵会掉落一个苹果。Bessie有过很多练习,只要她站在一棵有苹果落下的树下,就能接住一个苹果。Bessie可以很快地在两棵树之间行走,时间忽略不计。她可以随时站在一棵树下。此外,奶牛没有得到大量的锻炼,所以她不愿意在树间来回地来回行走(因此错过了一些苹果)。 苹果下降T(1 < = T< = 1000)分钟。Bessie愿意来回走至多W(1 < = W< = 30)次。考虑哪棵树每分钟会掉落一个苹果,确定贝西能抓到的最大数量的苹果。贝西从树1开始。
Input:Line 1: Two space separated integers: T and W * Lines 2..T+1: 1 or 2: the tree that will drop an apple each minute.
Output:Line 1: The maximum number of apples Bessie can catch without walking more than W times.
Sample Input
7 2
2
1
1
2
2
1
1
Sample Output
6

分析:

设dp[i][j]为从i时间开始(不包括i)还剩j次可以移动的时候,可以得到的苹果最大数目;

写出递推式子:

dp[i][j]=max{dp[i+1][j]+可能接到的苹果,dp[i+1][j-1]+可能接到的苹果}   (j-1>=0)

dp[i][0]=dp[i+1][0];

dp[t][j]=0;

容易看出递推方向为从下到上,从左到右,每一次递推的时候,通过记录的tree数组判断是否可以接到苹果即可,判断的方法是看已经用了几次移动,模一下2就可以了

代码:

#include<iostream>
#include<cstring>
using namespace std;
int dp[1010][40],tree[1010];
int main(){
	memset(dp,0,sizeof(0));
	int n,t,now;
	cin>>n>>t;
	for(int i=1;i<=n;i++){
		cin>>tree[i];
	}
	for(int i=n-1;i>=0;i--){
		for(int j=0;j<=t;j++){
			if((t-j)%2==0)now=1;
			else now=2;
			if(j==0){
				if(tree[i+1]==now)dp[i][j]=dp[i+1][j]+1;
				else dp[i][j]=dp[i+1][j];
				continue;
			}
			int x,y;
			if(tree[i+1]==now){
				x=dp[i+1][j-1];y=dp[i+1][j]+1;
			}
			else{
				x=dp[i+1][j-1]+1;y=dp[i+1][j];
			}
			dp[i][j]=max(x,y);
		}
	}
	cout<<dp[0][t];
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41333528/article/details/80161706