问题: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
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 1Sample 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; }