基礎動態規劃-POJ2385(Apple Catching)

描述

Description

It is a little known fact that cows love apples. Farmer John has two apple trees (which are conveniently numbered 1 and 2) in his field, each full of apples. Bessie cannot reach the apples when they are on the tree, so she must wait for them to fall. However, she must catch them in the air since the apples bruise when they hit the ground (and no one wants to eat bruised apples). Bessie is a quick eater, so an apple she does catch is eaten in just a few seconds.

Each minute, one of the two apple trees drops an apple. Bessie, having much practice, can catch an apple if she is standing under a tree from which one falls. While Bessie can walk between the two trees quickly (in much less than a minute), she can stand under only one tree at any time. Moreover, cows do not get a lot of exercise, so she is not willing to walk back and forth between the trees endlessly (and thus misses some apples).

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.
    Output

  • Line 1: The maximum number of apples Bessie can catch without walking more than W times.

實質上

是在求一個數組連續的奇數或者偶數位置的和,但是我們可以變換位置即,連續求奇數位置的和後變換到求偶數位置的和。變換的次數有限制不超過W次。

遞推(控制問題規模)

仔細想想我們通過,位置i和次數w可以控制問題的規模,那麼我們設dp[i][w] 爲在位置i,並且我們變換了w次,最大的累計和。
dp[i][w]=max(dp[i-1][w-1]+dp[i-2][w])+cur[i]
可以這樣理解,到當前位置爲止,我們累計和,可以是來自上個爲止的如果相差2,說明奇數偶數性沒有改變,我們不需要用到次數,是上個位置i-2,次數還是w,如果來自i-1這個位置,說明到這個位置用了一次變換之後變換的總數是w,所以可能來自,i-1位置上,用了w-1次變換後的結果。
當然他們倆誰大取誰的值。

邊界條件

需要注意我們人爲的設置,比如在0的位置上,變換爲1時候的值爲-1,以此來約束。

代碼實現

#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
using namespace std;

int dp[1000/2+1][30+1];
int main(){
    int w,t;
    vector<int> apple;
    cin>>t>>w;
    int c=-1;
    
    for(int i=0;i<t;i++){
        cin>>c;
        apple.push_back(c);
    }
    
    vector<int> apple_sum;
    int cnt=0;
    for(int i=0;i<t;){
        c=apple[i];
        cnt=0;
        while(c<t&&apple[i]==c){
            cnt++;
            i++;
        }
        apple_sum.push_back(cnt);
    }
    
    //init
    dp[0][0]=apple_sum[0];
    dp[1][0]=apple_sum[1];
    for(int i=2;i<apple_sum.size();i++){
        dp[i][0]=dp[i-2][0]+apple_sum[i];
    }
    //對於移動了j>0次到達0位置的,我們人爲的設置成-1,代表以這個爲基礎的後續問題,永遠都不會達到最大。
    for(int j=1;j<=w;j++){
        dp[0][j]=-1;
    }
    
    
    for(int i=1;i<apple_sum.size();i++){
        for(int j=1;j<=w;j++){
            if(i-2>=0)
                dp[i][j]=max(dp[i-2][j],dp[i-1][j-1])+apple_sum[i];
            else
                dp[i][j]=dp[i-1][j-1]+apple_sum[i];
        }
    }
    int res=0;
    for(int i=0;i<=w;i++)
    {
        res=max(res,dp[apple_sum.size()-1][i]);
        res=max(res,dp[apple_sum.size()-2][i]);
    }
    cout<<res<<endl;
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章