题目:http://acm.hdu.edu.cn/showproblem.php?pid=1085
母函数问题,分步求解一个一个进行
#include <iostream>
using namespace std;
int c1[10000], c2[10000];
int num[4];
int main()
{
int nNum;
while(scanf("%d %d %d", &num[1], &num[2], &num[3]) && (num[1]||num[2]||num[3]))
{
int _max = num[1]*1+num[2]*2+num[3]*5;
for(int i=0; i<=_max; ++i)
{
c1[i] = 0;
c2[i] = 0;
}
for(int i=0; i<=num[1]; ++i)
c1[i] = 1;
for(int i=0; i<=num[1]; ++i)
for(int j=0; j<=num[2]*2; j+=2)
c2[j+i] += c1[i];
for(int i=0; i<=num[2]*2+num[1]*1; ++i)
{
c1[i] = c2[i];
c2[i] = 0;
}
for(int i=0; i<=num[1]*1+num[2]*2; ++i)
for(int j=0; j<=num[3]*5; j+=5)
c2[j+i] += c1[i];
for(int i=0; i<=num[2]*2+num[1]*1+num[3]*5; ++i)
{
c1[i] = c2[i];
c2[i] = 0;
}
int i;
for(i=0; i<=_max; ++i)
if(c1[i] == 0)
{
printf("%d\n", i);
break;
}
if(i == _max+1)
printf("%d\n", i);
}
return 0;
}
****************************************
母函数变化的模板,
#include<iostream>
using namespace std;
int c1[8005],c2[8005];
int main()
{
int num[4],m[4]={0,1,2,5},sum;
int i,j,k;
while(scanf("%d%d%d",&num[1],&num[2],&num[3]))
{
if(num[1]==0&&num[2]==0&&num[3]==0)
break;
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
for( i=0; i<=num[1]; i++)
{
c1[i]=1;
c2[i]=0;
}
sum=num[1];
for( i=2; i<=3; i++)
{
for( j=0; j<=sum; j++)
for(int k=0; k<=m[i]*num[i]; k+=m[i])
{
c2[j+k]+=c1[j];
}
sum+=num[i]*m[i];
for( j=0; j<=sum; j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
int f=0;
for( i=0; i<=sum; i++)
if(c1[i]==0)
{
printf("%d\n",i);
f=1;
break;
}
if(!f)
printf("%d\n",sum+1);
}
return 0;
}
再给大家看看简单的规律的代码:
这个题的条件恰好可以这样做........
其实1,2两种钱可以组成a+2*b当中的任意一种价值,
如果a+2*b>=4的话,它和5又能组成1~9中任意一种价值。
所以和N个5加在一起会组成在范围之内所有的数字
#include <cstdio>int main()
{
int a, b ,c;
while( true )
{
scanf( "%d %d %d", &a, &b, &c );
if( a==0 && b==0 && c==0 )
break;
if( a==0 )
printf( "1\n" );
else if( a+2*b<4 )
printf( "%d\n", a+2*b+1 );
else
printf( "%d\n", a+2*b+5*c+1 );
}
}