DP - 完全背包(求方案总数) - 买书
小明手里有n元钱全部用来买书,书的价格为10元,20元,50元,100元。
问小明有多少种买书方案?(每种书可购买多本)
输入格式
一个整数 n,代表总共钱数。
输出格式
一个整数,代表选择方案种数。
数据范围
0≤n≤1000
输入样例1:
20
输出样例1:
2
输入样例2:
15
输出样例2:
0
输入样例3:
0
输出样例3:
1
分析:
将 手 中 的 钱 视 作 背 包 容 量 m , 书 的 价 格 视 作 物 品 体 积 v i , 问 题 转 化 为 完 全 背 包 问 题 , 求 方 案 总 数 。 将手中的钱视作背包容量m,书的价格视作物品体积v_i,\\问题转化为完全背包问题,求方案总数。 将手中的钱视作背包容量m,书的价格视作物品体积vi,问题转化为完全背包问题,求方案总数。
状 态 表 示 : f [ i ] [ j ] : 考 虑 前 i 种 物 品 且 体 积 不 超 过 m 的 方 案 总 数 。 状 态 计 算 : ① 、 不 包 含 第 i 种 物 品 : f [ i ] [ j ] = f [ i − 1 ] [ j ] 。 ② 、 包 含 第 i 种 物 品 : f [ i ] [ j ] = f [ i − 1 ] [ j − v [ i ] ] , j > = v [ i ] 。 状态表示:f[i][j]:考虑前i种物品且体积不超过m的方案总数。\\状态计算:\\①、不包含第i种物品:f[i][j]=f[i-1][j]。\\②、包含第i种物品:f[i][j]=f[i-1][j-v[i]],j>=v[i]。 状态表示:f[i][j]:考虑前i种物品且体积不超过m的方案总数。状态计算:①、不包含第i种物品:f[i][j]=f[i−1][j]。②、包含第i种物品:f[i][j]=f[i−1][j−v[i]],j>=v[i]。
总 计 : f [ i ] [ j ] = f [ i − 1 ] [ j ] + f [ i − 1 ] [ j − v [ i ] ] , j > = v [ i ] 。 边 界 : f [ 0 ] [ 0 ] = 1 。 可 优 化 为 一 维 。 总计:f[i][j]=f[i-1][j]+f[i-1][j-v[i]],j>=v[i]。\\边界:f[0][0]=1。\\可优化为一维。 总计:f[i][j]=f[i−1][j]+f[i−1][j−v[i]],j>=v[i]。边界:f[0][0]=1。可优化为一维。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1010;
int v[5]={0,10,20,50,100};
int n,f[N];
int main()
{
cin>>n;
f[0]=1;
for(int i=1;i<=4;i++)
for(int j=v[i];j<=n;j++)
f[j]+=f[j-v[i]];
cout<<f[n]<<endl;
return 0;
}