poj 2385 Apple Catching (DP)
Apples fall (one each minute) for T (1 <= T <= 1,000) minutes. Bessie is willing to walk back and forth at most W (1 <= W <= 30) times. Given which tree will drop an apple each minute, determine the maximum number of apples which Bessie can catch. Bessie starts at tree 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.
* 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
........................................................................................................................................
这个开始的时候没思路,后来仔细想了想,就有些思路了。
ap[2][t+1]:二维数组保存第i(t>=i>=1)秒时下落的一个苹果,下落就存为1,反之存为0.
a[i][j][k]:还剩 i 秒时且还有 j 次可移动时在 k 树下可以得到的最大苹果树。由此可以得到:
a[i][j][k]=max( a[i-1][j][k] + ap[k][t-i+1] , a[i-1][j-1][1-k] + ap[1-k][t-i+1] )
然后就是一些初值:
i 为0时:a[i][j][k]=0
j为0时:a[i][j][k]=for( i --> t ) sum ap[k][i]
然后就可以循环递推求结果了
#include <cstdio> #include <cstring> #include <iostream> #include <cmath> #include <algorithm> using namespace std; int main() { int i,j,k; int t,w; cin>>t>>w; int a[t+1][w+1][2]; int ap[2][t+1],x; for(i=1; i<=t; i++) { scanf("%d",&x); if(x==1) { ap[0][i]=1; ap[1][i]=0; } else { ap[0][i]=0; ap[1][i]=1; } } int m; for(i=0; i<=t; i++) { for(j=0; j<=w; j++) { for(k=0; k<2; k++) { if(i==0)a[i][j][k]=0; else if(j==0) { int s=0; for(m=t; m>t-i; m--) { s+=ap[k][m]; } a[i][j][k]=s; } else { a[i][j][k]=max(a[i-1][j][k]+ap[k][t-i+1],a[i-1][j-1][1-k]+ap[1-k][t-i+1]); } } } } /* for(i=0; i<=t; i++) { for(j=0; j<=w; j++) { for(k=0; k<2; k++) { printf("%d,%d,%d:%d ",i,j,k,a[i][j][k]); } printf("\n"); } printf("\n"); } */ printf("%d\n",a[t][w][0]); return 0; }

浙公网安备 33010602011771号