对近期hdu母函数问题的一些总结
hdu 1398 Square Coins
最基础的普通母函数
有n种硬币,每种硬币都有不同的价值,若需要组合出总价值m,问有多少种组合方式。硬币个数没有限制。
2011-08-29 20:19:35 | Accepted | 1398 | 15MS | 332K | 797 B | G++ | Tiramitu |

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 300
using namespace std;
int c1[MAXN+10],c2[MAXN+10];//表示展开式中x^k的系数
int main(void)
{
int n,i,j,k;
while(cin>>n)
{
if(!n)
break;
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
c1[0]=1;
for(i=1;i<=17;i++)//使用前i种钱币的情况,即母函数展开前i个多项式的乘积
{
for(j=0;j<=n;j++)//求新的多项式中的系数
for(k=0;k+j<=n;k+=i*i)
c2[j+k]+=c1[j];
for(j=0;j<=n;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
cout<<c1[n]<<endl;
}
return 0;
}
hdu 1028 Ignatius and the Princess III
2011-08-29 16:13:09 | Accepted | 1028 | 15MS | 328K | 511 B | G++ | Tiramitu |

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define MAXN 200
using namespace std;
int c1[MAXN],c2[MAXN];
int main(void)
{
int n;
while(cin>>n)
{
int i,j,k;
for(i=0;i<=n;i++)
{
c1[i]=1;
c2[i]=0;
}
for(i=2;i<=n;i++)
{
for(j=0;j<=n;j++)
for(k=0;k+j<=n;k+=i)
c2[j+k]+=c1[j];
for(j=0;j<=n;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
cout<<c1[n]<<endl;
}
return 0;
}
hdu 1085 Holding Bin-Laden Captive!
这个题比上面两个多了一个限制:个数限制
2011-08-29 20:15:45 | Accepted | 1085 | 15MS | 396K | 719 B | G++ | Tiramitu |

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
int a[4]={0,1,2,5},b[4];
int c1[8010],c2[8010];
int main(void)
{
while(cin>>b[1]>>b[2]>>b[3])
{
if(b[1]+b[2]+b[3]==0)
break;
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
int i,j,k;
int sum=0;
for(i=1;i<=3;i++)
sum+=a[i]*b[i];
c1[0]=1;
for(i=1;i<=3;i++)
{
for(j=0;j<=sum;j++)
{
if(c1[j])
for(k=0;k<=a[i]*b[i]&&k+j<=sum;k+=a[i])
c2[j+k]+=c1[j];
}
for(j=0;j<=sum;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
for(i=0;;i++)
if(!c1[i])
break;
cout<<i<<endl;
}
return 0;
}
hdu 1171 Big Event in HDU
先把所有可能的值求出来以后,再从sum/2开始枚举。
2011-08-29 21:26:07 | Accepted | 1171 | 796MS | 2688K | 809 B | G++ | Tiramitu |

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
int a[60],b[60];
int c1[300100],c2[300100];
int main(void)
{
int n;
while(cin>>n)
{
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
if(n<0)
break;
if(n==0)
continue;
int i,j,k;
int sum=0;
for(i=1;i<=n;i++)
{
cin>>a[i]>>b[i];
sum+=a[i]*b[i];
}
c1[0]=1;
for(i=1;i<=n;i++)
{
for(j=0;j<=sum;j++)
{
if(c1[j])
for(k=0;k+j<=sum&&k<=a[i]*b[i];k+=a[i])
c2[k+j]+=c1[j];
}
for(j=0;j<=sum;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
for(i=sum/2;i<=sum;i++)
if(c1[i])
{
i=i>sum-i?i:sum-i;
break;
}
cout<<i<<" "<<sum-i<<endl;
}
return 0;
}
hdu 2069 Coin Change
居然限制了银币总数!!所以还要加一个循环~~~
2011-08-30 09:58:07 | Accepted | 2069 | 15MS | 560K | 723 B | G++ | Tiramitu |

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
int num[251]={0};
int coin[10]={0,1,5,10,25,50};
int c1[260][110],c2[260][110];
int main(void)
{
ios::sync_with_stdio(false);
c1[0][0]=1;
int i,j,k,t;
for(i=1;i<=5;i++)
{
for(j=0;j<=250;j++)
{
for(k=0;k*coin[i]+j<=250;k++)
{
for(t=0;t+k<=100;t++)
{
c2[k*coin[i]+j][t+k]+=c1[j][t];
}
}
}
for(j=0;j<=250;j++)
for(t=0;t<=100;t++)
{
c1[j][t]=c2[j][t];
c2[j][t]=0;
}
}
for(i=1;i<=250;i++)
for(j=1;j<=100;j++)
num[i]+=c1[i][j];
num[0]=1;
while(cin>>i)
cout<<num[i]<<endl;
return 0;
}