概述
原题链接
思路:
求最大价值的同时更新最大方案;
因为所有不放物品也算一种方案,所以初始化所有
c
n
t
[
i
]
=
1
cnt[i] = 1
cnt[i]=1
如果
f
[
j
−
v
[
i
]
]
>
f
[
j
]
f[j - v[i]] > f[j]
f[j−v[i]]>f[j] 说明用当前物品的体积比不用当前物品的体积大,那就先更新最大价值,使
f
[
j
]
=
f
[
j
−
v
[
i
]
]
+
w
[
i
]
f[j] = f[j - v[i]] + w[i]
f[j]=f[j−v[i]]+w[i],同时更新
c
n
t
[
j
]
cnt[j]
cnt[j],因为当前情况下,用前i个物品体积为j时,是通过用
i
−
1
i - 1
i−1个物品体积为
j
−
v
[
i
]
j - v[i]
j−v[i] 时加上当前这一件物品得来的,所以方案数就等于
i
−
1
i - 1
i−1个物品体积为
j
−
v
[
i
]
j - v[i]
j−v[i] 时的方案数,此时的方案数是
f
[
j
]
=
f
[
j
−
v
[
i
]
]
f[j] = f[j - v[i]]
f[j]=f[j−v[i]].
如果 f [ j − v [ i ] ] = = f [ j ] f[j - v[i]] == f[j] f[j−v[i]]==f[j] 说明用第 i i i种物品和不用第 i i i种物品价值一样,那么此时的方案数 c n t [ j ] cnt[j] cnt[j]就由用第i种物品的方案和不用第i种物品的方案加起来,因为都可以使体积为 j j j,所以当前的方案数是 f [ j ] + = f [ j − v [ i ] ] . f[j] += f[j - v[i]]. f[j]+=f[j−v[i]].
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10, mod = 1e9 + 7 ;
int v[N], w[N], f[N], cnt[N];
int main()
{
int n, m; cin >> n >> m;
for (int i = 1; i <= n; i ++ )
{
cin >> v[i] >> w[i];
}
for (int i = 0; i <= m; i ++ ) cnt[i] = 1;
for (int i = 1; i <= n; i ++ )
{
for (int j = m; j >= v[i]; j -- )
{
if (f[j - v[i]] + w[i] > f[j])
{
f[j] = f[j - v[i]] + w[i];
cnt[j] = cnt[j - v[i]];
}
else if (f[j] == f[j - v[i]] + w[i])
{
cnt[j] += cnt[j - v[i]];
}
cnt[j] %= mod;
}
}
cout << cnt[m] << endl;
return 0;
}
最后
以上就是现实酸奶为你收集整理的背包问题求方案数(最大价值的方案数)思路:的全部内容,希望文章能够帮你解决背包问题求方案数(最大价值的方案数)思路:所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复