蓝桥杯官网题目:2.包子凑数

链接:题目点这里

首先要知道一个数学定理裴蜀定理,还有完全背包的基本运用,这里只介绍前者

也可以看一下我的个人理解,我是第一次听说这个定理,理解可能有误差。

  • 假设gcd(a,b)=d,gcd是最大公约数的意思。即a,b的最大公约数是d
  • ax+by=m(x,y是任意整数,可正可负)
  • 对于所有的m,一定会被d整除,即m%d=0

可以尝试画出ax+by=z的三维立体图,很显然是一个空间平面。

z是一个未知数,它的取值有无数个,如果在三维坐标系中看,那么是所有的z(z可以被gcd(a,b)整除)。

换句话说,ax+by表示的数的集合是{实数中所有的可以被gcd(a,b)整除的数}。

  • 以下考虑a,b互质

  • a,b如果是互质的,那么
    g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1

  • 那么ax+by可以构成所有的整数:

    {ax+by | x ∈ x\in x∈N, y ∈ y\in y∈N, a x + b y ∈ ax+by\in ax+by∈N}

  • 当x,y都是正整数的时候,包括0。ax+by不能表示的最小数是:
    ( a − 1 ) ∗ ( b − 1 ) − 1 (a-1)*(b-1)-1 (a−1)∗(b−1)−1

  • 也就是说,ax+by可以表示大于(a-1)*(b-1)-1的所有正整数

回到题目

看懂了上面的数学基础应该这个题就比较清晰了。

那我就直接上代码了,不懂的评论区留言

cpp 复制代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e4+1;  //只需要比ax+by的最小值大1就可以了。
const int M = 110;
long long int dp[N];  //dp[i]=j表示取i种包子的方案数是j
//dp[i]=dp[i-a[1]]+dp[i-a[2]]+dp[i-a[3]]+....+dp[i-a[n]]; 
//即,取i种包子的方案数等于取[i-a[1]]包子的方案数+[i-a[2]]包子的方案数+...+[i-a[n]]包子的方案数
int a[M];
int sum = 0;

int gcd(int a, int b)  //辗转相除法
{
    if (a < b)swap(a, b);  //大的数是被除数
    int r = a % b;   //余数
    if (r == 0)return b;
    else
    {
        a = b;
        b = r;
    }
    return gcd(a, b);
}

int main()
{
    int n;
    cin >> n;
    int k;
    for (int i = 1; i <= n; i++)  //找最大公约数
    {
        cin >> a[i];
        if (i == 1)k = a[i];
        else
            k = gcd(k, a[i]);
    }

    if (k != 1)cout << "INF";   //如果最大公约数不是1,那么就会有无穷个数取不到。

    else  //说明最大公约数是1,那么ax+by的值是所有1的倍数,ax+by此时表示整数集(所有整数)
    {
        sort(a + 1, a + n + 1);
        dp[0] = 1;  //取0种包子的方案数是1,即不取,这个必须要有,是很重要的边界初始化
        for (int i = 1; i <= N; i++)  //枚举包子的个数
        {
            for (int j = 1; j <= n; j++)  //然后更新当前包子个数的方案数
            {
                if (i - a[j] < 0)
                    break;
                dp[i] += dp[i - a[j]];
            }
            if (dp[i] == 0)  //退出内嵌for循环判断i个包子的方案数是否是0,如果是,说明这个数不能被构成
                sum++;
        }
        cout << sum << endl;
    }
    return 0;
}

对裴蜀定理有兴趣的可以关注我这篇博客,我会从cf和leetcode等网站更新相关内容,将会以链接形式帖在本篇下面

相关推荐
laocooon52385788618 分钟前
C语言 有关指针,都要学哪些内容
c语言·数据结构·算法
多多*41 分钟前
牛客周赛 Round 114 Java题解
算法
他们叫我一代大侠1 小时前
Leetcode :模拟足球赛小组各种比分的出线状况
算法·leetcode·职场和发展
Nebula_g1 小时前
C语言应用实例:硕鼠游戏,田忌赛马,搬桌子,活动选择(贪心算法)
c语言·开发语言·学习·算法·游戏·贪心算法·初学者
AI科技星2 小时前
张祥前统一场论动量公式P=m(C-V)误解解答
开发语言·数据结构·人工智能·经验分享·python·线性代数·算法
海琴烟Sunshine2 小时前
leetcode 345. 反转字符串中的元音字母 python
python·算法·leetcode
geobuilding2 小时前
将大规模shp白模贴图转3dtiles倾斜摄影,并可单体化拾取建筑
算法·3d·智慧城市·数据可视化·贴图
jghhh012 小时前
基于高斯伪谱法的弹道优化方法及轨迹仿真计算
算法
mm-q29152227294 小时前
【天野学院5期】 第5期易语言半内存辅助培训班,主讲游戏——手游:仙剑奇侠传4,端游:神魔大陆2
人工智能·算法·游戏
MoRanzhi12034 小时前
Python 实现:从数学模型到完整控制台版《2048》游戏
数据结构·python·算法·游戏·数学建模·矩阵·2048