DP 揹包 垃圾陷阱

2022-05-24 13:51:09 字數 1272 閱讀 5896

我的 \(dp\) 好菜啊。。。

其實不難看出這個題是揹包的,但問題是應該怎樣設計轉移。

可以看到題目一共給了 \(4\) 個狀態:當前時間,當前高度,當前生命,當前垃圾。

那對於這四個狀態,我們該如何處理呢?

首先可以考慮到,我們在列舉垃圾的時候,為了保證時間有序從而使維持的生命時間足夠轉移到下一情況這一限制成立,需要按照垃圾扔下的時間排序。

對時間排序後,當前時間這一維實際就可以消掉了,因為只要某乙個狀態高度大於 \(d\) 了,由於時間單調,它一定是時間最早的。

那麼對於剩餘的狀態,我們可以進行如下的設計:

f[i][j]表示當前的垃圾為 \(i\),深度為 \(j\) 時能維持的最大生命時間。

然後就可以很方便的進行揹包的轉移了,但是注意,當我們不用乙個垃圾放置於腳下時,是要將它吃掉的。

如果我們不能登上頂部時,是需要輸出 \(10 + 垃圾總時間\) 的。

**:

# include # include # include # include # define maxg 105

# define maxd 105

# define maxt 1005

struct garbagegar[maxg];

int f[maxg][maxd]; // 前 i 個垃圾到高度 j 獲得的最長生命時間

bool cmpg(garbage x, garbage y)

int main()

std::sort(gar+1, gar+g+1, cmpg);

memset(f, ~0x3f, sizeof(f));

f[0][0] = 10;

int ans = 0;

for(int i = 1; i <= g; i++)

if(j + gar[i].hei >= d)

f[i][j+gar[i].hei] = std::max(f[i][j+gar[i].hei], f[i-1][j] - (gar[i].tim-gar[i-1].tim));

f[i][j] = std::max(f[i][j], f[i-1][j] + gar[i].lif - (gar[i].tim-gar[i-1].tim));

} ans = std::max(ans, f[i][0] + gar[i].tim);

} printf("%d", ans);

return 0;

}

LUOGU P1156 垃圾陷阱(揹包變形)

首先應該看得出是乙個揹包吧 那dp陣列的第一維肯定有前i個物品 那第二維放啥呢?血量?高度?時間?時間是完全可以排除的,因為牛肯定是在辣雞剛掉下的時候就使用它,而且對於subtask1 如果卡門可以爬出陷阱,輸出乙個整數表示最早什麼時候可以爬出 答案肯定剛好是某個辣雞下落的時間 血量呢?設dp i ...

luogu1156 垃圾陷阱 動態規劃 揹包dp

垃圾陷阱 luogu 1156 題目大意 holsteins在距離地面d英呎的地方,fj間隔時間ti會往下扔第i個垃圾。holsteins對待每乙個垃圾都會選擇吃掉或者墊高。holsteins有10個點兒的生命值,每個垃圾會給她提供f的生命值。每小時holsteins會消耗一定的生命值。問 hols...

Luogu P1156 垃圾陷阱 DP

f i j 表示在第i個垃圾,高度為j的最大生命值 轉移分三部分 如果j 當前垃圾的高度,且兩個垃圾間的時間小於等於上乙個狀態f i 1 j a i v 的生命值,則可以墊高度 如果j 當前垃圾的高度,且兩個垃圾間的時間小於等於上乙個狀態f i 1 j 的生命值,則可以吃 如果j 當前垃圾的高度,且...