蒜頭君去超市購物,他有一隻容量爲 V 的購物袋,同時他想買n 件物品,已知每件物品的體積 ivi和重要度pi。蒜頭君想知道,挑選哪些物品放入購物袋中,可以使得買到的物品重要度之和最大,且物品體積和不超過購物袋的容量。
輸入格式
第一行輸入兩個整數 VVV(1≤V≤10001 \leq V \leq 10001≤V≤1000)和nnn(1≤n≤1001 \leq n \leq 1001≤n≤100)。代表購物袋的總體積爲VVV,蒜頭君一共想買nnn 件物品。
接下來輸入 nnn 行,每行輸入兩個整數 viv_ivi 和 pip_ipi(1≤vi,pi≤1001 \leq v_i, p_i \leq 1001≤vi,pi≤100),分別表示每件物品的體積和重要度。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int max2=0;
int v,n,i,j;
scanf("%d%d",&v,&n);
int dp[v+10],w[n+10],p[n+10];
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
scanf("%d",&w[i]);
scanf("%d",&p[i]);
}
for(i=1;i<=n;i++)
{
for(j=v;j>=w[i];j--)
{
dp[j] = max(dp[j-w[i]]+p[i],dp[j]);
if(max2<=dp[j])
{
max2= dp[j];
}
}
}
printf("%d",max2);
return 0;
}
int max (int a,int b)
{
if(a>=b)
{
return a;
}else
{
return b;
}
}
輸出一行,輸出一個整數,表示蒜頭君能買到物品的最大重要度之和。
樣例輸入
樣例輸入
50 4 1 5 60 99 49 8 33 7
樣例輸出
13
我們看到的求最優解的揹包問題題目中,事實上有兩種不太相同的問法。有的題目要求“恰好裝滿揹包”時的最優解,有的題目則並沒有要求必須把揹包裝滿。一種區別這兩種問法的實現方法是在初始化的時候有所不同。
如果是第一種問法,要求恰好裝滿揹包,那麼在初始化時除了f[0]爲0其它f[1..V]均設爲-∞,這樣就可以保證最終得到的f[N]是一種恰好裝滿揹包的最優解。
如果並沒有要求必須把揹包裝滿,而是隻希望價格儘量大,初始化時應該將f[0..V]全部設爲0。
爲什麼呢?可以這樣理解:初始化的f數組事實上就是在沒有任何物品可以放入揹包時的合法狀態。如果要求揹包恰好裝滿,那麼此時只有容量爲0的揹包可能被價值爲0的nothing“恰好裝滿”,其它容量的揹包均沒有合法的解,屬於未定義的狀態,它們的值就都應該是-∞了。如果揹包並非必須被裝滿,那麼任何容量的揹包都有一個合法解“什麼都不裝”,這個解的價值爲0,所以初始時狀態的值也就全部爲0了。
這個小技巧完全可以推廣到其它類型的揹包問題,後面也就不再對進行狀態轉移之前的初始化進行講解。