完全背包
完全背包问题和基本的 0-1 背包问题非常类似,区别就是在完全背包问题中,每种物品有无限件。
从每种物品的角度考虑,求解完全背包问题的策略由对某种物品取或者不取变成了取0件、取1件、取2件……等很多种。按基本的01背包问题求解算法的思路,设 f[ i ][ v ] 表示前i种物品恰放入一个载荷能力为 v 的背包的最大价值。则状态转移方程为 f[ i ][ v ] = max{ f[ i - 1 ][ v - k * w[ i ] ] + k * p[ i ] | 0 <= k * p[ i ] <= v }。
核心代码:
for (i=1; i<=n; i++) //阶段:枚举每个物品
for (v=0; v<=M; v++) //状态:枚举背包载荷能力
for (k=1; k<=v div w[i]; k++) //决策
f[i][v]=max(f[i-1][v], f[i-1][v-k*w[i]]+k*p[i])
Dollar Dayz
题意:
农夫John去了在Cow Store的Dollar Days,发现有无限数量的工具在出售。在他第一次去的时候,这些工具以1美元、2美元和3美元的价格出售。农夫John正好有5美元,他可以买每件1美元的工具5个;或者买每件3美元的工具1个,然后买每件2美元的工具1个;等等;如果农夫John把所有的钱花在买工具上,那么就一共有5种不同的组合方式,如下所示:
1 @ US$3 + 1 @ US$2
1 @ US$3 + 2 @ US$1
1 @ US$2 + 3 @ US$1
2 @ US$2 + 1 @ US$1
5 @ US$1
请您编写一个程序,计算农夫John在Cow Store花费N美元(1 <= N <= 1000)可以购买工具的方式数,工具的价格成本从1美元到K美元(1 <= K <= 100)。
输入
输入一行,给出两个用空格分隔的整数:N和K。
输出
输出一行,给出农夫John花费他的钱的方式数。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
#define ll long long
ll inf=1000000000000000000;
ll a[1001];//低位
ll b[1001];//高位
int main()
{
int n,k;
scanf("%d%d",&n,&k);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
a[0]=1;
for(int j=1;j<=k;j++)
for(int i=j;i<=n;i++)
{
b[i]=(b[i]+b[i-j])+(a[i]+a[i-j])/inf;
a[i]=(a[i]+a[i-j])%inf;
}
if(b[n]) cout<<b[n];
cout<<a[n]<<endl;
return 0;
}