动态规划:POJ No 2385 Apple Catching

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
using namespace std;

int T, W;      //T 时间内 , W : 来回的次数
const int maxn = 1000 + 20;
int apple[maxn + 200];
/*
dp[i][j]: 给定时刻i, 转移次数已知为 j 
:即上一时刻同一棵树 或 上一时刻 不同的树 
:则这一时刻在转移次数为j的情况下最多能接到的苹果为:
 那两个状态的最大值 + 当前能接受到的苹果。
 
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1])
if (j % 2 + 1 == i ) {
    dp[i][j]++;
}
*/
int dp[maxn + 20][maxn + 20];

void solve()
{
    scanf("%d%d", &T, &W);
    for (int i = 1; i <= T; i++) {
        scanf("%d", &apple[i]);
    }
    
    memset(dp, 0, sizeof(dp));
    
    for (int i = 1; i <= T; i++) 
    {
        // j 为 转移次数 
        for (int j = 0; j <= W; 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]);
            }
            // j:转移次数,apple[i]:i时刻的树号 0, 1
            // j为偶数,在第一课树下时候 || 
            // j为奇数, 在第二课树下时候, 只有转移的时候,并且当前时刻也有苹果下降,才去+1
            if (j % 2 == apple[i] - 1) {  
                dp[i][j]++;
            }
        }    
    }
    int ans = dp[T][0];
  //已知T时刻,各个转移次数之间进行比较
for (int i = 1; i <= W; i++) { if (ans < dp[T][i]) { ans = dp[T][i]; } } printf("%d\n", ans); } int main() { solve(); return 0; }

 

posted @ 2017-04-28 01:21  douzujun  阅读(139)  评论(0编辑  收藏  举报