【动态规划】POJ2385-Apple Catching

【题目大意】

有两棵树1和2,奶牛Bessie位于树1下,每个单位时间会有一个苹果从其中一棵树掉下来,同时Bessie也可以移动一次,但是Bessie不希望移动超过W次,问T时间内Bessie最多得到多少个苹果。

【思路】

经典的动态规划,预处理时将树1和树2分别用0和1来表示。由于移动偶数次可以回到树1,移动奇数次可以回到树2,移动j次时,若j%2==a[i]就表明当前位置恰好有苹果落下。

设f[i][j]为第i个苹果掉下来的时候,移动至多j次可以得到的最多苹果。f[i][j]由f[i-1][j]和f[i-1][j-1]转移过来,对于f[i-1][j-1]又分为当前移动和不移动两种情形。

如果之前已经跑了j次,不动的情况下苹果恰好又掉下来就加一,f[i-1][j]+(j%2==a[i]);

如果之前已经跑了j-1次,再跑动一次,此时恰好苹果掉下来就加一,f[i-1][j-1]+(j%2==a[i]);

果之前已经跑了j-1次,这次不跑动,此时恰好苹果掉了下来就加一,f[i-1][j-1]+((j-1)%2==a[i])。

以上三种情况就可组成状态转移方程。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 const int MAXNt=1000+50;
 7 const int MAXNw=30+5;
 8 int t,w;
 9 int a[MAXNt];
10 int f[MAXNt][MAXNw];
11 /*f[i][j]表示第i个苹果掉下来,且跑动了j次的时候能够抓到的最多苹果数*/ 
12 
13 int main()
14 {
15     scanf("%d%d",&t,&w);
16     
17     memset(f,0,sizeof(f));
18     f[0][0]=0;
19     /*第零个苹果掉落下来的时候,移动零次最多得到零个苹果*/ 
20     for (int i=1;i<=t;i++)
21     {
22         scanf("%d",&a[i]);
23         f[i][0]=f[i-1][0]+(a[i]==1);
24         /*如果当前站在第一棵树的下面,那么不动的情况下可以多抓到一个苹果*/
25         a[i]--; 
26         /*将站爱第一棵树下的设为0,站在第二课树下的设为1*/ 
27     }
28      
29     for (int i=1;i<=t;i++)
30         for (int j=1;j<=w;j++)
31         {
32             f[i][j]=max(f[i][j],f[i-1][j]+(j%2==a[i]));
33             /*如果之前已经跑了j次,不动的情况下苹果恰好又掉下来,则加1*/
34             f[i][j]=max(f[i][j],f[i-1][j-1]+(j%2==a[i]));
35             /*如果之前已经跑了j-1次,再跑动一次,此时恰好苹果掉下来,则加1*/
36             f[i][j]=max(f[i][j],f[i-1][j-1]+((j-1)%2==a[i]));
37             /*如果之前已经跑了j-1次,这次不跑动,此时恰好苹果掉了下来,则加1*/
38         }
39     cout<<f[t][w]<<endl;
40     return 0;
41 }

 

posted @ 2015-08-17 14:30  iiyiyi  阅读(405)  评论(0编辑  收藏  举报