您的位置:首页 > 其它

母函数的一些问题:Ignatius and the Princess III&&Square Coins&&选课时间(题目已修改,注意读题)&&Holding Bin-Laden Captive!

2013-07-31 22:18 579 查看
首先给出基本的模板:也就是以前所说的公式(不是什么很难的东西)

#include <iostream>

using namespace std;

const int lmax=10000;

int c1[lmax+1],c2[lmax+1];

int main()

{ int n,i,j,k;

while (cin>>n)

{for (i=0;i<=n;i++)

{c1[i]=0; c2[i]=0; }

for (i=0;i<=n;i++) c1[i]=1;

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
<<endl;

}

return 0;

 }//此公式的具体应用还是看例子。

Ignatius and the Princess III HDU1028

就是一个整数拆分的题目:求有几种拆法。

先来个递归的超时的代码,理解下题目。

#include <iostream>
using namespace std;
int s(int a,int b)
{
if(a==1||b==1) return 1;
if(a<b) return s(a,a);
if(a==b) return (s(a,b-1)+1);
if(a>b) return (s(a,b-1)+s(a-b,b));
}
int main()
{
int n;
while(cin>>n)
cout<<s(n,n)<<endl;//给出一个数,先从他本身开始拆。
return 0;
}


之后是母函数的:(对比公式进行理解)第一种情况

母函数是建立在多项式的乘法上的,先要理解(1+X+X^2+X^3......)*(1+X^2+X^4+X^6......)*(1+X^3+X^6+X^9......).......得出的aX^n,a为凑成n的方法数。母函数的核心是一个三重循环,其中,关于母函数的题目有三种:一,1,2,3,4,5......这样+1,+1的,并且不限数量,如:整数拆分;二:不限数量,但是每个数都是另给出的,如 Square Coins;第三种是数是另给出的,并且限制了数量,数量也是另给出的。

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
int i,j,k,n;
int c1[205],c2[205];
while(scanf("%d",&n)!=EOF)
{
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[k+j]+=c1[j];
for(j=0;j<=n;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
printf("%d\n",c1
);
}
return 0;
}


Square Coins HDU1398


#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;

int main()
{
int a[17]={1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289};
int i,c1[305],c2[305],j,k,n;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
for(i=0;i<=n;i++)
{
c1[i]=1;c2[i]=0;
}
for(i=1;i<17;i++)
{
for(j=0;j<=n;j++)
for(k=0;k+j<=n;k+=a[i])//这里的第二种情况,不同的数用数组来表示
c2[k+j]+=c1[j];
for(j=0;j<=n;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
printf("%d\n",c1
);
}
return 0;
}


选课时间(题目已修改,注意读题) HDU2079

第三种情况:限制了数量并且数是不同的。

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
int a[10],b[10],c1[45],c2[45];
int main()
{
int t,n,m,i,j,k;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=0;i<m;i++)
scanf("%d%d",&a[i],&b[i]);
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
c1[0]=1;
for(i=0;i<m;i++)
{
for(j=0;j<=n;j++)
for(k=0;k<=a[i]*b[i]&&k+j<=n;k+=a[i])
c2[k+j]+=c1[j];
for(j=0;j<=n;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
printf("%d\n",c1
);
}
return 0;
}


Holding Bin-Laden Captive! HDU1085

一个母函数的简单变行:通过这么几个例子应该对母函数很深刻了吧。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int c1[8005],c2[8005];
int main()
{
int x,y,z,i,j,k,s;
while(scanf("%d%d%d",&x,&y,&z)!=EOF)
{
if(x==0&&y==0&&z==0)
break;
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
for(i=0;i<=x;i++)
c1[i]=1;
s=x+2*y;
for(j=0;j<=s;j++)
for(k=0;k+j<=s&&k<=2*y;k+=2)
c2[k+j]+=c1[j];
for(j=0;j<=s;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
s+=5*z;
for(j=0;j<=s;j++)
for(k=0;k+j<=s&&k<=5*z;k+=5)
c2[k+j]+=c1[j];
for(j=0;j<=s;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
for(i=1;i<=s;i++)
{
if(c1[i]==0)
break;
}
printf("%d\n",i);
}
}


来个就是公式的代码:对比就知道改了些什么了。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int c1[8005],c2[8005];
int main()
{
int a,b,c,s,a1[3],b1[3],i,j,k;
a1[0]=1;a1[1]=2;a1[2]=5;
while(scanf("%d%d%d",&a,&b,&c)!=EOF)
{
if(a==0&&b==0&&c==0)
break;
s=a+2*b+c*5;
for(i=0;i<=s;i++)
{c1[i]=0;c2[i]=0;}
c1[0]=1;b1[0]=a;b1[1]=b;b1[2]=c;
for(i=0;i<3;i++)
{
for(j=0;j<=s;j++)
for(k=0;k+j<=s&&k<=a1[i]*b1[i];k+=a1[i])
c2[k+j]+=c1[j];
for(j=0;j<=s;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
for(i=1;i<=s;i++)
{
if(c1[i]==0)
break;
}
printf("%d\n",i);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: