01背包问题求体积恰好等于V的方案数
原题链接AcWing278. 数字组合

考虑状态表示:
f[i][j]表示考虑前1~i个物品,体积恰好为j时的方案数(不考虑前1~i个物品组合后的价值,只考虑组合后的体积)
状态转移:
可以分两种情况
选第i个物品使得体积为j
不选第i个物品使其体积为j
第i个物品体积为v,价值为w
可以发现f[i][j]由上述两种情况构成,所以
f[i][j]=f[i-1][j]+f[i-1][j-v]
因为是体积恰好是j,所以初始化时
memset(f,0,sizeof f)
f[0][0]=1;
再对空间复杂度进行优化
代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int M=10010;
int f[M];//f[i][j]表示考虑前1~i个物品,体积恰好为j时的方案数
int main(){
int n,m;
cin>>n>>m;
f[0]=1;
for(int i=0;i<n;i++){
int v;
scanf("%d",&v);
for(int j=m;j>=v;j--)
f[j]=f[j]+f[j-v];
}
cout<<f[m]<<endl;
return 0;
}
完全背包问题求体积恰好等于V的方案数
原题链接AcWing 1023. 买书

物品数量无限,这是一道完全背包求方案数问题
考虑状态表示:
f[i][j]表示考虑前1~i个物品,体积恰好为j时的方案数(不考虑前1~i个物品组合后的价值,只考虑组合后的体积)
状态转移:
可以分多种情况
不选第i个物品使其体积为j f[i-1][j]
选1个第i个物品使得体积为j f[i-1][j-v]
选2个第i个物品使得体积为j f[i-1][j-2*v]
.....
选s个第i个物品使得体积为j f[i-1][j-s*v]
第i个物品体积为v,价值为w
可以发现f[i][j]由上述s+1种情况构成,所以
f[i][j]=f[i-1][j]+f[i-1][j-v]+f[i-1][j-2*v]+.....+f[i-1][j-s*v]
而
f[i][j-v]=f[i-1][j-v]+f[i-1][j-2*v]+.....+f[i-1][j-s*v]
所以
f[i][j]=f[i-1][j]+f[i][j-v]
因为是体积恰好是j,所以初始化时
memset(f,0,sizeof f)
f[0][0]=1;
再对空间复杂度进行优化
代码如下:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int N=1010;
int f[N];
int d[4]={
10,20,50,100};
int main(){
int n;
cin>>n;
f[0]=1;
for(int i=0;i<4;i++)
for(int j=d[i];j<=n;j++)
f[j]

文章介绍了如何使用动态规划解决01背包问题和完全背包问题,包括求方案数和最优选法的方案数。对于每个问题,文章详细阐述了状态表示、状态转移方程,并提供了相应的C++代码实现。
最低0.47元/天 解锁文章
3147

被折叠的 条评论
为什么被折叠?



