惡補一下DP 揹包專題 刷刷水題 L2

2022-08-05 14:18:17 字數 2119 閱讀 6685

開心的金明

題目大意

就是求一定揹包容量的最大值

思路想必大家都知道,一看到這種題目,就會想起01揹包

雖然特別簡單但是還是講一下吧

狀態設定

由於這題差不多是一個01揹包的版子題,那麼我們就只需要一個一維的陣列去記錄狀態

f[i]中i代表的是揹包容量,而f[i]的值則代表該容量下的最大值

轉移方程

f[i]=max(f[i],f[i-揹包容量]+揹包價值)

輸出輸出的話我們就只需要輸出f[揹包容量]就可以啦

這個簡單的dp題就講完啦

**在這裡

小a點菜

題目大意

就是要求花光所有錢的方案數

思路最開始我還不懂,發現題解的說法好有道理

我們設定一個二維陣列來統計選到第i種物品花j的錢的方案數

最後我們就只要輸出選到第n種物品話光全部錢的方案數

狀態設定

f[i][j]中i代表現在選到第幾種物品,j代表花的錢數

轉移方程

1.如果我們列舉的錢數大於菜的**即(j>a[i])

f[i][j]=f[i-1][j]+f[i-1][j-a[i]];//這2個式子相加分別代表不選這種物品和選這種物品,但是**不變的方案數

2.如果我們列舉的錢數等於菜的**即(j==a[i])

f[i][j]=f[i-1][j]+1//這2個值相加代表不選這種物品和選的方案數,由於我們不方便將f[i][0]定義為1,所以這裡就特判處理一下(是這麼理解的吧...)

3.如果小於

f[i][j]=f[i-1][j]//直接轉移過來就可以啦

輸出直接輸出f[n][m]

#includeusing

namespace

std;

intn,m;

int a[1005

];int f[110][10010

];int scan()//

快讀撒

returnas;

}int

main()

for(int i=1;i<=n;i++)//

在這裡面,i就像一個分層,所以我們沒有必要倒著來

}cout

<

return0;

}/*思路:這題的話最開始有點蒙

現在來理一下思路

1.我們設定狀態f[i][j],i是前i中,j是前,值為種數

2.f[i][j]=f[i-1][j]+f[i-1][j-a[i]];//這種轉移只是一個向前走的過程

f[i][j]=f[i-1][j]+1;//這種是方案新增

f[i][j]=f[i-1][j];//相當於不選擇這種商品

大概是這樣子吧

.........

dp還是要多練一練啊

*/

**在這裡

金明的**

讓我拖一會,先把簡單題寫完233333

瘋狂的採藥

題目描述

這個題目實質上就是一個求完全揹包的問題

思路我們就設定一個一維陣列來記錄相應容量的最大值

狀態設定

f[i]中i代表容量,f[i]是該容量的值

轉移方程

由於這個不是01揹包,而是完全揹包,所以我們列舉時要正著列舉,而不是像01揹包一樣倒著列舉

f[i]=max(f[i],f[i-a[i]]);

輸出直接輸出f[m]就可以了...

#includeusing

namespace

std;

intt,n;

int f[100010]=;

struct

ssa[

10010

];int

scan()

return f*as;}

intmain()

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

}cout

<

return0;

}/*思路:我們只需要開一個一維陣列,來表示揹包的容量,

然後我們只需要在01揹包的基礎上將容量從小列舉到大

*/

**在這裡