买不到的数目
题目链接-买不到的数目
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。
输入格式
两个正整数,表示每种包装中糖的颗数(都不多于1000)
输出格式
一个正整数,表示最大不能买到的糖数
样例输入1
4 7
样例输出1
17
样例输入2
3 5
样例输出2
7
解题思路
- 思路一
数论
如果a,b均是正整数且互质,那么由 ax+by,x≥0,y≥0不能凑出的最大数是(a−1)(b−1)−1
引理:给定a,b,若gcd(a,b)>1,则一定不能凑出最大数 - 具体操作见代码
附上代码
#include<bits/stdc++.h>
#define int long long
#define lowbit(x) (x &(-x))
using namespace std;
const int INF=0x3f3f3f3f;
const int dir[4][2]={-1,0,1,0,0,-1,0,1};
const double PI=acos(-1.0);
const double eps=1e-10;
const int M=1e9+7;
const int N=1e5+5;
typedef long long ll;
typedef pair<int,int> PII;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,m;
cin>>n>>m;
cout<<(n-1)*(m-1)-1<<endl;
return 0;
}
- 思路二
dp - 用bool数组dp[i]表示能否组合成i,将
dp[0]
,dp[n]
和dp[m]
都置为1 - for循环遍历,每遍历到一个数,都要看看
dp[i - n]
或dp[i -m]
是否为1,如果是,则置true,否则就更新ans - 从n和m中较大的数开始遍历,遍历到
n*m
即可,因为我们已经将dp[0]
,dp[n]
和dp[m]
都置为1,且易得比n*m
大的数必定可以被n,m组合 ans
就是指最大不能买的数目,循环结束,便可直接输出ans
- 具体操作见代码
附上代码
#include<bits/stdc++.h>
#define int long long
#define lowbit(x) (x &(-x))
using namespace std;
const int INF=0x3f3f3f3f;
const int dir[4][2]={-1,0,1,0,0,-1,0,1};
const double PI=acos(-1.0);
const double eps=1e-10;
const int M=1e9+7;
const int N=1e6+5;
typedef long long ll;
typedef pair<int,int> PII;
bool dp[N];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,m,ans;
cin>>n>>m;
dp[0]=1;
dp[n]=dp[m]=1;
int maxn=max(n,m);
for(int i=maxn;i<n*m;i++){
if(dp[i-n]||dp[i-m])
dp[i]=1;
else
ans=i;
}
cout<<ans<<endl;
return 0;
}