a*p+b*q=m模型
买不到的元素
说实话想法不够严谨,你可以理解为1~nm为一个循环周期,也就是从nm+1 ~ 2nm这个周期开始,其中任何一个数都可以由第一个周期对应的数加上nm得到。那么如果最大不可凑成的数超过nm,比如nm+k,那么2nm+k,3n*m+k也必然凑不出来,不就无解了吗,这只是个人不太严谨的推理哈~~~
#include <iostream>
#include <algorithm>
using namespace std;
int n, m, minn, maxx, ans;
bool dp[1000000];
int main() {
cin >> n >> m;
dp[0] = true;
minn = min(n, m);
maxx = max(n, m);
for (int i = minn; i < n * m; i++) {
if (dp[i - minn]) {
dp[i] = true;
} else if (i >= maxx && dp[i - maxx]) {//防止越界
dp[i] = true;
} else {
ans = i;
}
}
cout << ans;
return 0;
}
包子凑数
裴蜀定理 任意两个数凑出的数是gcd的倍数
(1)如果gcd不是1 那么有任意一个数凑不出来
(2)如果gcd是1 那么最大不能表示的数字 (a-1)*(b-1)-1
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
int q[N];
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
bool dp[105][N];
int main()
{
int n;cin>>n;
int d=0;
for (int i = 1; i <= n; i ++ ) {cin >> q[i];
d=gcd(d,q[i]);
}
if(d!=1) {
cout <<"INF" <<endl;
}
else {
dp[0][0]=true;
for (int i = 1; i <= n; i ++ ){//
for (int j = 0; j < 10000; j ++ ){//可以表示的数字 这里表示为体积
dp[i][j]=dp[i-1][j];
if(j>=q[i]){
dp[i][j]|=dp[i][j-q[i]];
}
}
}
int res=0;
for (int i = 0; i < 10000; i ++ ){
if(!dp[n][i])
res++;
}
cout << res;
}
return 0;
}