题目描述
原题链接:1205.买不到的数目
解题思路
1.有解的情况
当 g c d ( a , b ) = c > 1 gcd(a, b) =c\gt1 gcd(a,b)=c>1的时候,设 a = p c , b = q c a=pc,b=qc a=pc,b=qc,则 a x + b y = k c ax+by=kc ax+by=kc,那么一个数只要它不能被 c c c整除,那么它就不能被 a a a和 b b b组合而成,因此就没有解。
2.方法1:打表查看规律
当 n = 3 n=3 n=3时,
/*
3 4 5
3 5 7
3 7 11
3 8 13
3 10 17
*/
可以看到 m m m每增加1,结果都会增加2
继续尝试当 n = 4 n=4 n=4时:
/*
4 5 11
4 7 17
4 9 23
4 11 29
4 13 35
可以看出当 m m m每增加1,结果都会增加3。
大胆猜测,当
n
=
3
n=3
n=3时,结果应该是
2
m
−
x
1
2m-x_1
2m−x1
当
n
=
4
n=4
n=4时,结果应该是
3
m
−
x
2
3m-x_2
3m−x2
因此得出规律,结果应该是
(
n
−
1
)
∗
m
−
x
(n-1)*m -x
(n−1)∗m−x,而根据对称性,
n
n
n和
m
m
m的形式应该相同,因此变形一下就是
(
n
−
1
)
∗
(
m
−
1
)
−
x
(n-1)*(m-1)-x
(n−1)∗(m−1)−x,带入一下数字可以求得
x
=
1
x=1
x=1。
因此最后的公式就是:
r
e
s
=
(
n
−
1
)
∗
(
m
−
1
)
−
1
res=(n-1)*(m-1)-1
res=(n−1)∗(m−1)−1
3.方法2:动态规划
枚举从
1
1
1到
1
0
6
+
100
10^6+100
106+100的数,假如这个数比
n
n
n或
m
m
m大,那么说明这个数就可以被
n
n
n或
m
m
m拓展而来。
即:
s
t
[
i
]
=
s
t
[
i
−
n
]
∣
s
t
[
i
−
m
]
st[i]=st[i-n]|st[i-m]
st[i]=st[i−n]∣st[i−m]
代码
方法1( o ( 1 ) o(1) o(1))
#include<iostream>
using namespace std;
int main()
{
int n,m;
cin >> n >> m;
cout << (n-1) * (m-1) - 1;
return 0;
}
方法2( o ( n ) o(n) o(n))
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1000100;
int n,m;
bool st[N];
int main()
{
cin >> n >> m;
st[0] = true;
st[n] = true;
st[m] = true;
for(int i = min(n, m); i < N; i++)
{
if(i-m >= 0) st[i] = st[i-m];
if(i-n >= 0) st[i] = st[i] | st[i-n];
}
int ans = 0;
for(int i = 1; i < N; i++)
if(!st[i]) ans = i;
cout << ans;
}