(DP)买不到的数目【蓝桥杯】(裴蜀定理)

买不到的数目

小明开了一家糖果店。

他别出心裁:把水果糖包成4颗一包和7颗一包的两种。

糖果不能拆包卖。

小朋友来买糖的时候,他就用这两种包装来组合。

当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。

你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。

大于17的任何数字都可以用4和7组合出来。

本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。

输入格式

两个正整数 n,m,表示每种包装中糖的颗数。

输出格式

一个正整数,表示最大不能买到的糖数。

数据范围

2≤n,m≤1000,保证数据一定有解。

输入样例:

4 7

输出样例:

17

前提条件:给定a,b,若d=gcd(a,b)>1(即最大公约数>1),则一定不能凑出最大数。

因为若d>1,则a和b一定是d的倍数,那么a和b凑出来的数也肯定是d的倍数,所以一定不会存在一个最大数,使得这个数之后的数字都能被a和b凑出来

结论: 如果 a,b均是正整数且互质,那么由 ax+by,x≥0,y≥0不能凑出的最大数是 (a−1)(b−1)−1(这是定理,证明很难,记住定理即可)

互质:最大公约数为1

裴蜀定理:若a,b的最大公约数为d,怎一定存在两个整数p,q使得ap+bq=d,只要ab互质,则一定有解

若ab互质,则一定存在ap+bq=1,两边同时乘以m  =>  apm+bqm=m  =>  (am-q)p+(bm+p)q=m

方法1. 暴力搜索(打表找规律,会超时,AC50%)

        当要凑的数字减到0的时候,说明凑出来了
        先尝试用p来凑,要凑的数字变成m-p
        再尝试用q来凑,要凑的数字变成m-q
        如果都凑不出来,则返回false

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m,ans;
bool dfs(int m,int p,int q){
	if(!m) return true;
	if(m>=p&&dfs(m-p,p,q)) return true;
	if(m>=q&&dfs(m-q,p,q)) return true;
	return false;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=1000;i++){
		if(!dfs(i,n,m)) ans=i;
	}
	cout<<ans<<endl;
	return 0;
}

根据这个暴力搜索我们可以打表找规律,如下:

3 2 1
3 4 5
3 5 7
3 7 11
3 8 13


大致可以发现规律为n=3时,m+1,ans+2
故ans=2m+x
代入数据得x=-3
推得公式为ans=2m-3;(n=3)
同理,多推几个公式

4 7 17
4 9 23
4 11 29

ans=3m-4(n=4)
最后整理得到大致公式ans=(n-1)*(m-1)-1.

方法2.利用公式直接输出答案:(p-1)(q-1)-1

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int main(){
	cin>>n>>m;
	cout<<(n-1)*(m-1)-1<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_56501550/article/details/129860128
今日推荐