acwing 11. 揹包問題求方案數

傳送門

描述

有 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章