盤點一個語音轉換庫
1267:【例9.11】01揹包問題
時間限制: 1000 ms 記憶體限制: 65536 KB
提交數: 28735 通過數: 17213
【題目描述】
一個旅行者有一個最多能裝 MM 公斤的揹包,現在有 nn 件物品,它們的重量分別是W1,W2,...,WnW1,W2,...,Wn,它們的價值分別為C1,C2,...,CnC1,C2,...,Cn,求旅行者能獲得最大總價值。
【輸入】
第一行:兩個整數,MM(揹包容量,M<=200M<=200)和NN(物品數量,N<=30N<=30);
第2..N+12..N+1行:每行二個整數Wi,CiWi,Ci,表示每個物品的重量和價值。
【輸出】
僅一行,一個數,表示最大總價值。
【輸入樣例】
10 4 2 1 3 3 4 5 7 9
【輸出樣例】
12
······(此處省略999+字)
看了上面的內容,大家一定知道了什麼是01揹包了吧。
好,我們分析一下題目:
設f[i][v]表示前i件物品,總重量不超過v的最優值
所以:
則f[n][m]為最優解。
下面是程式碼環節:
#include<cstdio>
using namespace std;
const int maxm=201,maxn=31;
int m,n;
int w[maxn],c[maxn];
int f[maxn][maxm];
int max(int x,int y)
int max(int x,int y){
}
int main(){
}
這是主框架↑
顧名思義,有max函式,裡面的程式碼,我就不多說了。
int max(int x,int y){
if(x<y) return y;
else return x;
}
main裡的程式碼
int main(){
scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++) scanf("%d%d",&w[i],&c[i]);
//上面的是輸入
for(int i=1;i<=n;i++){
for(int v=m;v>0;v--){
if(w[i]<=v) f[i][v]=max(f[i-1][v],f[i-1][v-w[i]]+c[i]);
else f[i][v]=f[i-1][v];
}
}
//
//f[i][v]表示前i件物品,總重量不超過v的最優值,套公式就可以
printf("%d",f[n][m]);
// f[n][m]為最優解。
return 0;
}
連起來的程式碼(圖片):
當然這不是最好的方法。
更好的方法,程式碼當然少,不用寫函式:
這個方法優化了空間複雜度,保對。
第一種方法↑
第二種方法↑