代码如下:
#include<iostream>
using namespace std;
int a[105],f[105][10005],w[105],g[105][10005];
int n,V;
int main()
{
g[0][0]=1;
cin>>V>>n;
for(int i=1;i<=n;i++)
{
cin>>w[i]>>a[i];
}
for(int i=1;i<=n;i++)
{
for(int j=V;j>=0;j--)
{
if(j-w[i]>=0)
f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+a[i]);
else
f[i][j]=f[i-1][j];
if(f[i][j]==f[i-1][j])
g[i][j]+=g[i-1][j];
if(f[i][j]==f[i-1][j-w[i]]+a[i])
g[i][j]+=g[i-1][j-w[i]];
}
}
cout<<f[n][V]<<endl;
cout<<g[n][V]<<endl;
return 0;
}
这个代码同时解决了01背包的最大价值的问题和最大方案数的问题
g[i][v]表示在装i个物品的情况下装体积为v的物品的所有装载方式。
和01背包类似的,这个东西也符合最优子结构原理:根据g[0][0]往后递推。
例:一开始初始了g[0][0]为1,那么g[0][0+w[i]]的方案数是1,g[1][0]的方案数也是1,那么必然会有一些解会重叠起来(假设数据所能构造的方案数大于2),这就符合最优子结构,可以一路滚去g[n][v]。(一个点可能滚了很多个1.。。)【语文不及格=。=】优化:
可以把数组降到一维
代码如下:
暂时写不出。。