AcWing 1023 买书

题目描述:

小明手里有n元钱全部用来买书,书的价格为10元,20元,50元,100元。

问小明有多少种买书方案?(每种书可购买多本)

输入格式

一个整数 n,代表总共钱数。

输出格式

一个整数,代表选择方案种数。

数据范围

0≤n≤1000

输入样例1:

20

输出样例1:

2

输入样例2:

15

输出样例2:

0

输入样例3:

0

输出样例3:

1

分析:

本题要求用n元钱买四种不同价格书的方案数,且n元钱必须全部花光,每本书买的数量没有限制,属于完全背包问题的应用。状态表示f[i][j]表示在前i种书中买了总价格是j的书的方案数。状态转移方程为f[i][j] = f[i-1][j] + f[i-1][j-v] + f[i-1][j-2v] + ... +f[i-1][j-kv],kv <= j。又f[i][j-v] = f[i-1][j-v] + f[i-1[j-2v] + ... + f[i-1][j-kv],kv <= j,故得到优化后的状态转移方程f[i][j] = f[i-1][j] + f[i][j-v]。下面讨论边界状态,f[0][0]=0表示什么都不买也没花钱的方案数是1,f[0][j] = 0,j > 0,表示什么都不买却花了j元的方案是不存在的。采用滚动数组实现的话,f[i][j]只用到了上一层的f[i-1][j]以及当前层的f[i][j-v]状态,所以顺序枚举买书的价格即可。(完全背包问题的详细分析见AcWing 3 完全背包问题)。

#include 
#include 
using namespace std;
const int N = 1005;
int v[] = {0,10,20,50,100};
int f[N];
int main(){
    int n;
    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<

 

你可能感兴趣的:(算法提高课,背包模型,动态规划)