免費餡餅 基礎DP

2021-09-11 10:22:33 字數 1681 閱讀 9574

kuangbin帶你飛【專題十二 基礎dp1 】

都說天上不會掉餡餅,但有一天gameboy正走在回家的小徑上,忽然天上掉下大把大把的餡餅。說來gameboy的人品實在是太好了,這餡餅別處都不掉,就掉落在他身旁的10公尺範圍內。餡餅如果掉在了地上當然就不能吃了,所以gameboy馬上卸下身上的揹包去接。但由於小徑兩側都不能站人,所以他只能在小徑上接。由於gameboy平時老呆在房間裡玩遊戲,雖然在遊戲中是個身手敏捷的高手,但在現實中運動神經特別遲鈍,每秒種只有在移動不超過一公尺的範圍內接住墜落的餡餅。現在給這條小徑如圖示上座標:

為了使問題簡化,假設在接下來的一段時間裡,餡餅都掉落在0-10這11個位置。開始時gameboy站在5這個位置,因此在第一秒,他只能接到4,5,6這三個位置中其中乙個位置上的餡餅。問gameboy最多可能接到多少個餡餅?(假設他的揹包可以容納無窮多個餡餅)

## **思路:** 按照動態規劃的常規套路分為4步;

1.確定狀態

顯然,我們需要確定第k秒 在第i個位置的收益

我們發現第k秒在第i個點的收益等於前k - 1秒在(i - 1, i , i + 1)【假設三個值都處於0 - 10】三個值中取其中的乙個 + 當前點的收益;

所以我們設 dp[i][j]表示第i秒當前位置在j點的最大收益

它的子問題就是在i - 1秒 與 j點相連的兩個點的最大收益;

顯然這滿足最優子結構和無後效性

2.轉移方程

因為dp[i][j]這個點 只能由 dp[i - 1][j - 1], dp[i - 1][j]和 dp[i - 1][j + 1]這三個點轉移過來;

所以我們在外層迴圈列舉每個時間,內層列舉每個點。然後轉移是由上一層的j - 1, j , j + 1取乙個最優點即可;

即 dp[i][j] = max(dp[i - 1][j - 1], dp[i - 1][j], dp[i - 1][j + 1]) + val[i][j]

3.邊界情況與初始化

只需將0秒時,所有位置的收益初始化為0即可;

4.計算順序

顯然,我們需要dp[i][j]就需要上一層的dp[i - 1][j - 1] dp[i - 1][j] dp[i - 1][j + 1],所以我們從前往後轉移即可;

ps:

由於題目給出初始點在5這個點,所以dp[1][4] = val[1][4], dp[1][5] = val[1][5], dp[1][6] = val[1][6].其他秒按順序轉移即可;

我的**記錄的最大的時間和點,算是一種常數優化吧;

#include

using namespace std;

#define long long long

#define inf 0x3f3f3f3f

#define max_n 100010

int a[max_n]

, dp[max_n][20

], val[max_n][20

];intmain()

for(

int i =

1; i <= max_time; i++

)else}}

cout << max << endl;

}return0;

}

免費餡餅 (dp)

都說天上不會掉餡餅,但有一天gameboy正走在回家的小徑上,忽然天上掉下大把大把的餡餅。說來gameboy的人品實在是太好了,這餡餅別處都不掉,就掉落在他身旁的10公尺範圍內。餡餅如果掉在了地上當然就不能吃了,所以gameboy馬上卸下身上的揹包去接。但由於小徑兩側都不能站人,所以他只能在小徑上接...

免費餡餅(DP)

時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述都說天上不會掉餡餅,但有一天gameboy正走在回家的小徑上,忽然天上掉下大把大把的餡餅。說來gameboy的人品實在是太好了,這餡餅別處都不 掉,就掉落在他身旁的10公尺範圍內。餡餅如果掉在了地上當然就不能吃了,所以gamebo...

免費餡餅 (dp)

都說天上不會掉餡餅,但有一天gameboy正走在回家的小徑上,忽然天上掉下大把大把的餡餅。說來gameboy的人品實在是太好了,這餡餅別處都不掉,就掉落在他身旁的10公尺範圍內。餡餅如果掉在了地上當然就不能吃了,所以gameboy馬上卸下身上的揹包去接。但由於小徑兩側都不能站人,所以他只能在小徑上接...