您的位置:首页 > 其它

母函数 经典题目汇总

2017-04-14 15:20 344 查看

HDU 1398 Square Coins(普通母函数 || 完全背包)

题意: 可选钱 种类17种,值分别为    i*i(i>=1&&i<=17) 求组和之和=钱数K的方案数     分析:   方法一:
///DP   完全背包问题(求装入背包)
///f[i]表示
///打表
#include<stdio.h>
int main()
{
int a[20]={0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289},f[305]={0};
int i,n,j;
f[0]=1;
for(i=1;i<=17;i++)///第几种钱
for(j=a[i];j<=300;j++)///
f[j]+=f[j-a[i]];
while(scanf("%d",&n)!=EOF){
if(n==0)
break;
printf("%d\n",f
);
}
return 0;
}

方法二:

母函数

母函数应用于——————形式上说,普通型生成函数用于解决多重集的组合问题,而指数型母函数用于解决多重集的排列问题.。现在我们先讨论普通生成函数;

这里组合问题,用普通母函数

#include "cstdio"
#define N 305
int c1
;///记录各次幂系数
int c2
;///记录中间计算结果
void solve()
{
for(int i=0;i<=300;i++)///初始化(第一个表达式)
{
c1[i]=1;
c2[i]=0;
}
for(int i=2;i<=17;i++)///那个表达式
{
for(int j=0;j<=300;j++)
{
for(int k=0;k+j<=300;k+=i*i)///此表达式中各项的次幂
{                           ///(把组合问题的加法法则和幂级数的乘幂对应起来)
c2[j+k]+=c1[j];
}
}
for(int j=0;j<=300;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
}
int main()
{
int n;
solve();
while(~scanf("%d",&n),n)
{
printf("%d\n",c1
);
}
return 0;
}

 HDU1028 

Ignatius and the Princess III

题意:

输入一数N,求1-N N种数,任意组合(数不一定都出现和个数任意)之和=N的方案个数

分析:

组合问题

普通母函数

#include "cstdio"
#define N 305
int c1
;
int c2
;
void solve()
{
for(int i=0;i<=120;i++)
{
c1[i]=1;
c2[i]=0;
}
for(int i=2;i<=120;i++)
{
for(int j=0;j<=120;j++)
{
for(int k=0;k+j<=120;k+=i)
{
c2[k+j]+=c1[j];
}
}
for(int j=0;j<=120;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
}
int main()
{
int n;
solve();
while(scanf("%d",&n)!=EOF)
{
printf("%d\n",c1
);
}
}

 

HDU1085
题意:1 2 5三种数,你赋予他们数量,求他们组成和不能组成的最小数

个数有限

#include "cstdio"
#include "iostream"
#include "cstring"
using namespace std;
#define N 10000
int c1
;
int c2
;
int num[4];
int Max;
void solve()
{
num[1]*=2;num[2]*=5;
Max=num[0]+num[1]+num[2];
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
for(int i=0;i<=num[0];i++)
{
c1[i]=1;
}
for(int j=0;j<=num[0];j++)
for(int k=0;k+j<=num[0]+num[1];k+=2)
c2[k+j]+=c1[j];
for(int i=0;i<=num[0]+num[1];i++)
{
c1[i]=c2[i];c2[i]=0;
}
for(int j=0;j<=num[0]+num[1];j++)
for(int k=0;k+j<=num[0]+num[1]+num[2];k+=5)
c2[k+j]+=c1[j];
for(int i=0;i<=num[0]+num[1]+num[2];i++)
{
c1[i]=c2[i];c2[i]=0;
}
}
int main()
{
while(scanf("%d%d%d",&num[0],&num[1],&num[2])!=EOF&&(num[0]||num[1]||num[2]))
{
solve();
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);
}
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: