小明开了一家糖果店。
他别出心裁:把水果糖包成4颗一包和7颗一包的两种。
糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。
当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。
大于17的任何数字都可以用4和7组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。
输入格式
两个正整数 n,m,表示每种包装中糖的颗数。
输出格式
一个正整数,表示最大不能买到的糖数。
数据范围
2≤n,m≤1000
保证数据一定有解。
样例输入
4 7
样例输出
17
解题代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int m,n;
const int N = 1e6+10;
bool arr[N]={false};
int main()
{
cin>>m>>n;
arr[m]=true;
arr[n]=true;
for(int i=min(m,n);i<N;++i)
{
if(arr[i])
{
arr[i+m]=true;
arr[i+n]=true;
}
}
for(int i=N;i>0;--i)
{
if(!arr[i])
{
cout<<i<<endl;
break;
}
}
return 0;
}
解题思路:
本题一眼动态规划,但是我们这里需要思考的一个问题就是对于任何的m,n,是否有一个上限,使其超过这个上限之后,都可以获得?
这里留给读者去思考。
我们需要注意的是数据的范围为[0,1000],所以我们的最大范围为(1000)^2,也就是10^6。但是这里我习惯在这个基础上+10,也就是
const int N=1e6+10;
接下来我们定义一个布尔数组,用来记录能否得到该数组,我们初始化为false。
我们定义状态:
arr[i]=false,说明不能凑到i个糖果,arr[i]=true,说明可以凑到i个糖果
对于输入的m,n,肯定是可以得到的,所以我们这里初始化
arr[m]=true;
arr[n]=true;
接下来我们需要从m和n之间比较小的开始循环,一直循环到N。我们需要判断当前的数组arr[i]是否为true,当为true的时候,意思就是能凑得到当前的糖果数量,那么当前的数量+m和当前的数量+n都可以获得。
最后我们需要从最后开始遍历,当遍历到第一个false的时候,证明不能凑到该糖果。将其输出就行了。