51Nod1085 0-1揹包(一維和二維陣列實現)
阿新 • • 發佈:2018-11-09
揹包是典型的動態規劃問題,關於揹包問題的詳解,推薦部落格:點選開啟連結(這篇部落格有點錯誤,程式碼for迴圈裡錯了,不過講解 的很詳細)
題目如下:
在N件物品取出若干件放在容量為W的揹包裡,每件物品的體積為W1,W2……Wn(Wi為整數),與之相對應的價值為P1,P2……Pn(Pi為整數)。求揹包能夠容納的最大價值。
Input 第1行,2個整數,N和W中間用空格隔開。N為物品的數量,W為揹包的容量。(1 <= N <= 100,1 <= W <= 10000)第2 - N + 1行,每行2個整數,Wi和Pi,分別是物品的體積和物品的價值。(1 <= Wi, Pi <= 10000) Output 輸出可以容納的最大價值。 Sample Input
3 6 2 5 3 8 4 9
1
二維的太大的話容易超記憶體,寫小了容易WA,建議寫一維的。
下面是二維的程式碼:
#include<cstdio> #include<algorithm> #include<cstring> const int Max=10005; int w[105],p[105],f[105][Max]; //f的第二維要開大點,因為下面for迴圈第二維是從0一直到V using namespace std; int main() { int n,V; scanf("%d%d",&n,&V); memset(f,0,sizeof(f)); for(int i=1;i<=n;i++) scanf("%d%d",&w[i],&p[i]); for(int i=1;i<=n;i++){ for(int v=0;v<=V;v++){ if(v<w[i]) f[i][v]=f[i-1][v]; else f[i][v]=max(f[i-1][v],f[i-1][v-w[i]]+p[i]); } } printf("%d",f[n][V]); return 0; }
然後是一維的程式碼:
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int Max=10500; int w[105],p[105],f[Max]; //f要開大一點,因為下面for迴圈v是逐一取值遞減 int main() { int n,V; scanf("%d%d",&n,&V); memset(f,0,sizeof(f)); for(int i=1;i<=n;i++) scanf("%d%d",&w[i],&p[i]); for(int i=1;i<=n;i++){ for(int v=V;v>=w[i];v--){ f[v]=max(f[v],f[v-w[i]]+p[i]); } } printf("%d",f[V]); }