POJ 2385 Apple Catching(dp)

POJ 2385 Apple Catching

题意为每分钟两棵树中的一颗掉下一个苹果,约翰最开始在第一棵树,他最多走w步,问能捡到苹果数的最大值

分析:开始用递归来做,练练递归,果不其然超时了,那就用动态规划了

           状态:dp[i][j]表示前i分钟,移动j次所获得的最大苹果数

           状态转移方程:dp[i][j] = max(dp[i-1][j-1], dp[i-1][j];然后在考虑当前的位置能不能捡到苹果,能就dp[i][j]++;

代码:

#include<iostream>
#include<cstdio>
using namespace std;
const int MAX_T = 1000;
const int MAX_W  = 30;
int t, w;
int a[MAX_T];
int dp[MAX_T+1][MAX_W+1]; 
void solve() {
    if(a[0] == 1) {
        dp[0][0] = 1;
        dp[0][1] = 0;
    } else{
        dp[0][0] = 0;
        dp[0][1] = 1;
    }
    for(int i = 0; i < t; i++) {
        for(int j = 0; j <= w; j++) {
            if(!j) dp[i+1][j] = dp[i][j];
            else dp[i+1][j] = max(dp[i][j-1], dp[i][j]);
            if(i && j%2+1 == a[i]) dp[i+1][j]++;
        }
    } 
    int ans = 0;
    for(int i = 0; i <= w; i++) ans = max(ans, dp[t][i]);
    printf("%d
", ans);
}
int main() {
    scanf("%d%d", &t, &w);
    for(int i = 0; i < t; i++) scanf("%d", &a[i]);
    solve();
    return 0;
}

 该题还可以与01背包问题类似的优化,使用一维数组,减少空间的浪费

代码:

#include<iostream>
#include<cstdio>
using namespace std;
const int MAX_T = 1000;
const int MAX_W  = 30;
int t, w;
int a[MAX_T];
int dp[MAX_T+1]; 
void solve() {
    if(a[0] == 1) {
        dp[0] = 1;
        dp[1] = 0;
    } else{
        dp[0] = 0;
        dp[1] = 1;
    }
    for(int i = 0; i < t; i++) {
        for(int j = w; j >= 0; j--) {
            if(j) dp[j] = max(dp[j-1], dp[j]);
            if(i && j%2+1 == a[i]) dp[j]++;
        }
    } 
    int ans = 0;
    for(int i = 0; i <= w; i++) ans = max(ans, dp[i]);
    printf("%d
", ans);
}
int main() {
    scanf("%d%d", &t, &w);
    for(int i = 0; i < t; i++) scanf("%d", &a[i]);
    solve();
    return 0;
}
作者:kindleheart
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/kindleheart/p/8602387.html