题意
给出三个数
1
,
2
,
5
1,2,5
1,2,5,其数量分别为
a
1
,
a
2
,
a
3
a_{1}, a_{2}, a_{3}
a1,a2,a3,问这三个数不能凑出的最小数。
链接:link。
思路
对于这类组合计数问题,可以用生成函数解决,将计数问题转化为多项式乘法问题。相关知识请参考《组合数学》。
时间复杂度分析
多项式相乘与多项式最高次数有关,而多项式最高次数为 O ( a 1 + 2 a 2 + 5 a 3 ) \mathcal{O}(a_{1}+2a_{2}+5a_{3}) O(a1+2a2+5a3)。所以时间复杂度为 O ( ( a 1 + 2 a 2 + 5 a 3 ) 2 ) \mathcal{O}((a_{1}+2a_{2}+5a_{3})^{2}) O((a1+2a2+5a3)2)。
实现
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int N=8005;
int cnt[N],tmp[N];
int main(){
int a,b,c;
while(cin>>a>>b>>c&&(a||b||c)){
memset(tmp,0,sizeof(tmp));
for(int i=0;i<=a;i++){
for(int j=0;j<=2*b;j+=2){
tmp[i+j]+=1;
}
}
for(int i=0;i<=a+2*b;i++) cnt[i]=tmp[i];
memset(tmp,0,sizeof(tmp));
for(int i=0;i<=a+2*b;i++){
for(int j=0;j<=5*c;j+=5){
tmp[i+j]+=cnt[i];
}
}
for(int i=0;i<=a+2*b+5*c+1;i++){
if(!tmp[i]){
cout<<i<<endl;
break;
}
}
}
return 0;
}