程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> NOJ1060 接蘋果 二維DP

NOJ1060 接蘋果 二維DP

編輯:關於C++

題目描述

很少有人知道奶牛愛吃蘋果。農夫約翰的農場上有兩棵蘋果樹(編號為1和2), 每一棵樹上都長滿了蘋果。奶牛貝茜無法摘下樹上的蘋果,所以她只能等待蘋果 從樹上落下。但是,由於蘋果掉到地上會摔爛,貝茜必須在半空中接住蘋果(沒有人愛吃摔爛的蘋果)。貝茜吃東西很快,她接到蘋果後僅用幾秒鐘就能吃完。每一分鐘,兩棵蘋果樹其中的一棵會掉落一個蘋果。貝茜已經過了足夠的訓練, 只要站在樹下就一定能接住這棵樹上掉落的蘋果。同時,貝茜能夠在兩棵樹之間 快速移動(移動時間遠少於1分鐘),因此當蘋果掉落時,她必定站在兩棵樹其中的一棵下面。此外,奶牛不願意不停地往返於兩棵樹之間,因此會錯過一些蘋果。蘋果每分鐘掉落一個,共T(1<=T<=1000)分鐘,貝茜最多願意移動W(1<=W<=30) 次。現給出每分鐘掉落蘋果的樹的編號,要求判定貝茜能夠接住的最多蘋果數。 開始時貝茜在1號樹下。

輸入

第一行2個數,t和k。接下來的t行,每行一個數,代表在時刻t蘋果是從1號蘋果樹還是從2號蘋果樹上掉下來的。

輸出

對於每個測試點,輸出一行,一個數,為奶牛最多接到的蘋果的數量。


輸入樣例

7 2
2
1
1
2
2
1
1

輸出樣例

6(輸出注解:貝茜不移動直到接到從第1棵樹上掉落的兩個蘋果,然後移動到第2棵樹下,直到接到從第2棵樹上掉落的兩個蘋果,最後移動到第1棵樹下,接住最後兩個從第1 棵樹上掉落的蘋果。這樣貝茜共接住6個蘋果。)


解題思路

這是一題二維DP 我們用dp[i][j]表示到前i個蘋果,換了j次的最大蘋果數量。

假設我們現在已經考慮完了i-1的情況。

那麼如果第i個蘋果我們移動:有dp[i][j] = dp[i-1][j-1] + 當前位置是否有蘋果(0或1)

如果第i個蘋果我們不移動:有dp[i][j] = dp[i-1][j] + 當前位置是否有蘋果(0or1)

(當前位置:換了j次 如果j是奇數 那麼奶牛肯定在2號樹 如果j是偶數 那麼奶牛肯定是在1號樹)

下面我們考慮一下dp的初始化。做了幾道DP問題之後我發現DP問題最難的地方在建立DP數組 而最需要小心的地方則是DP數組的初始化,這題就跳進了一個陷阱。。。幸好及時發現了。

從狀態轉移方程我們知道要初始化dp[x][0]和dp[1][x]

dp[x][0] 即不移動 一直在1號樹下面 能接到多少自己腦補。。。

dp[1][x]即只考慮第一個蘋果 奶牛在下面移來移去。。。自己腦補


下面放代碼

#include 
#include 
#include 
const int maxpingguo= 1010;
const int maxyidong = 35;
using namespace std;
int dp[maxpingguo][maxyidong];
int apple[maxpingguo][3];//apple[i][j]=1為在第i分鐘j樹上有蘋果 這樣設計apple數組為下面的DP創造方便
int main()
{
    int pingguo,yidong;
    scanf("%d%d",&pingguo,&yidong);
    for(int i = 1 ; i <= pingguo ; i ++) {
        int t;
        scanf("%d",&t);
        apple[i][t] = 1;
    }
    //dp初始化
    for(int i = 1 ; i <= yidong ; i ++) {
        if(i%2) {
            if(apple[1][2]) dp[1][i] = 1;
            else dp[1][i] = 0;
        }else {
            if(apple[1][1]) dp[1][i] = 1;
            else dp[1][i] = 0;
        }
    }
    for(int i = 1  ; i <= pingguo ; i ++) {/*這裡有一個陷阱,一開始我覺得上面已經初始化過dp[1][1]了 所以直接從i=2走起了
                                            *但實際上如果yidong=0的情況下上面的初始化並不會執行!!
                                            */
        dp[i][0] = dp[i-1][0] +apple[i][1];
    }
    //dp
    for(int j = 1 ; j <= yidong ; j ++) {
        for(int i = 2 ; i <= pingguo ; i ++) {
            if(j%2) {
                dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]) +apple[i][2];
            }else {
                dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]) +apple[i][1];
            }
        }
    }
    int _max = -1;
    for(int i = 0 ; i <= yidong ; i ++) {
        if(_max < dp[pingguo][i]) _max = dp[pingguo][i];
    }
    printf("%d\n",_max);
    return 0;
}





  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved