You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

##AcWing 1021. 货币系统

【总结】背包问题的至多/恰好/至少

一、题目描述

给你一个n种面值的货币系统,求组成面值为m的货币有多少种方案。

输入格式 第一行,包含两个整数nm

接下来n行,每行包含一个整数,表示一种货币的面值。

输出格式 共一行,包含一个整数,表示方案数。

数据范围 n≤15,m≤3000

输入样例

3 10
1
2
5

输出样例

10

二、题目解析

本题与上一题买书问题基本一模一样,只是方案数可能很大,需要用long long来存储。

状态表示 f[i][j]: 用前i种面值的货币组成面值 恰好j的方案数

状态转移方程

\large f[i][j] = f[i-1][j] + f[i][j-v]

边界状态为f[i][0] = 1

三、实现代码

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;

const int N = 20;
const int M = 3010;
int n, m;
LL v[N];
LL f[M];

int main() {
    cin >> n >> m;
    f[0] = 1;
    for (int i = 1; i <= n; i++) {
        cin >> v[i];
        for (int j = v[i]; j <= m; j++)
            f[j] += f[j - v[i]];
    }
    printf("%lld\n", f[m]);
    return 0;
}

四、 重复组合公式

计算公式n个不同的元素每次取出r个元素的 允许重复 组合总数为:

\large F(n,r)=C_{n+r-1}^r

证明

  • 插板法原理 考虑这样一个问题:把10个苹果分给3人,每人至少分1个,有多少种分法?

我们这样考虑:把10个苹果分给3人,我们就要在9个空格里面插入2块板,就会分为3部分,且每部分都至少1个,故有C_9^{2}种。如图的插板方式,就是甲分3个,乙分5个,丙分2个。

  • 变式1 将上述问题略加变化:把10个苹果分给3人,每人可以不分,有多少种分法?

这时我们要向第一种情况转化,可以假设甲、乙、丙三人本来都有苹果,他们都拿一个苹果出来,一起分,这样他们每人就至少要一个苹果了。

我们就要在9+3=12个空格里面插入2块板,就会分为3部分,且每部分都至少1个,故有C_{12}^2种。如图的插板方式,就是甲分3-1=2个,乙分8-1=7个,丙分2-1=1个。

  • 变式2 继续深入讨论:把10个苹果分给3人,甲至少要2个,乙至少要3个,丙可以不要,有多少种分法?

我们还要向第一种情况转化,可以假设先给甲1个、给乙2个、而丙自己先拿出来1个,这样他们分余下的苹果时,每人至少要一个苹果就可以了

我们就要在9-3+1=7个空格里面插入2块板,就会分为3部分,且每部分都至少1个,故有C_7^2种。如图的插板方式,就是甲分3+1=4个,乙分2+2=4个,丙分3-1=2个。

高中数学题练习链接

回到本题,理解为 变式2, 每个盒子里可以没有被选择的数字,也就是0个,为了适应 隔板法,通过构造的办法,我们认为每个盒子先拿出来一个,这样,最起码它最后能有1个,也就是n+r个小球,此时,可以放隔板的位置就是n+r-1个,需要选择的位置数是r

\large F(n,r)=C_{n+r-1}^r

证毕

利用公式估算数据范围

\LARGE C_{3000+15-1}^{3000}=C_{3014}^{14}=\frac{3014!}{14!\times 3000!}=\frac{3001\times ... \times 3014}{14!}

最坏的情况 上面我们的思考和假设,都是 一样的小球,也就是对应着所以货币的面额都是1,要求组合成价值3000的货币,每种货币无个数限制。

由于题目中说了,每种货币的价值并不相同,也就是上面论述的每个盒子里面不能随意放入最多r个小球,受每个盒子上限不同的限制。根据公式求出的数值,肯定是大于真实的数值。

按公式计算出的数值,要大于int的范围,如果此题数据为最坏情况,那么long long也会爆掉。