傳送門
描述
有 N 件物品和一個容量是 V 的揹包。每件物品只能使用一次。
第 i 件物品的體積是 vi,價值是 wi。
求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。
輸出 最優選法的方案數。注意答案可能很大,請輸出答案模 109+7 的結果。
輸入格式
第一行兩個整數,N,V,用空格隔開,分別表示物品數量和揹包容積。
接下來有 N 行,每行兩個整數 vi,wi,用空格隔開,分別表示第 i 件物品的體積和價值。
輸出格式
輸出一個整數,表示 方案數 模 109+7 的結果。
數據範圍
0<N,V≤1000
0<vi,wi≤1000
輸入樣例
4 5
1 2
2 4
3 4
4 6
輸出樣例:
2
對於這道題我們首先應該找到方案數的狀態轉移方程
if(dp[j] < dp[j - a] + b) dp[j] = dp[j - a] + b, f[j] = f[j - a];
else if(dp[j] == dp[j - a] + b) f[j] = (f[j] + f[j - a]) % mod;
dp數組記錄當前重量的最大價值,f數組記錄當前重量最大價值的對應方案數
AC代碼如下:
#include<bits/stdc++.h>
using namespace std;
int dp[1010],f[1010];
const int mod=1e9+7;
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<=m;i++)f[i]=1;
for(int i=0;i<n;i++)
{
int a,b;
cin>>a>>b;
for(int j=m;j>=a;j--)
{
if(dp[j]<dp[j-a]+b) dp[j]=dp[j-a]+b,f[j]=f[j-a];
else if(dp[j]==dp[j-a]+b) f[j]=(f[j]+f[j-a])%mod;
}
}
cout<<f[m]<<endl;
return 0;
}