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

首先给出基本的模板:也就是以前所说的公式(不是什么很难的东西)

#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[n]<<endl;
  }
  return 0;

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

Ignatius and the Princess III HDU1028

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

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

 

 1 #include <iostream>
 2 using namespace std;
 3 int s(int a,int b)
 4 {
 5     if(a==1||b==1) return 1;
 6     if(a<b) return s(a,a);
 7     if(a==b) return (s(a,b-1)+1);
 8     if(a>b) return (s(a,b-1)+s(a-b,b));
 9 }
10 int main()
11 {
12     int n;
13     while(cin>>n)
14         cout<<s(n,n)<<endl;//给出一个数,先从他本身开始拆。
15     return 0;
16 }

 

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

母函数是建立在多项式的乘法上的,先要理解(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;第三种是数是另给出的,并且限制了数量,数量也是另给出的。

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 using namespace std;
 5 int main()
 6 {
 7     int i,j,k,n;
 8     int c1[205],c2[205];
 9     while(scanf("%d",&n)!=EOF)
10     {
11         for(i=0;i<=n;i++)
12         {
13             c1[i]=1;
14             c2[i]=0;
15         }
16         for(i=2;i<=n;i++)
17         {
18             for(j=0;j<=n;j++)
19                 for(k=0;k+j<=n;k+=i)
20                     c2[k+j]+=c1[j];
21         for(j=0;j<=n;j++)
22         {
23             c1[j]=c2[j];
24             c2[j]=0;
25         }
26         }
27         printf("%d\n",c1[n]);
28     }
29     return 0;
30 }

Square Coins HDU1398

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     int a[17]={1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289};
 9     int i,c1[305],c2[305],j,k,n;
10     while(scanf("%d",&n)!=EOF)
11     {
12         if(n==0)
13             break;
14     for(i=0;i<=n;i++)
15     {
16         c1[i]=1;c2[i]=0;
17     }
18     for(i=1;i<17;i++)
19     {
20         for(j=0;j<=n;j++)
21             for(k=0;k+j<=n;k+=a[i])//这里的第二种情况,不同的数用数组来表示
22             c2[k+j]+=c1[j];
23         for(j=0;j<=n;j++)
24         {
25             c1[j]=c2[j];
26             c2[j]=0;
27     }
28         }
29         printf("%d\n",c1[n]);
30     }
31     return 0;
32 }

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

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

 

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<stdio.h>
 4 #include<string.h>
 5 using namespace std;
 6 int a[10],b[10],c1[45],c2[45];
 7 int main()
 8 {
 9     int t,n,m,i,j,k;
10     scanf("%d",&t);
11     while(t--)
12     {
13         scanf("%d%d",&n,&m);
14         for(i=0;i<m;i++)
15             scanf("%d%d",&a[i],&b[i]);
16         memset(c1,0,sizeof(c1));
17         memset(c2,0,sizeof(c2));
18         c1[0]=1;
19         for(i=0;i<m;i++)
20         {
21             for(j=0;j<=n;j++)
22                 for(k=0;k<=a[i]*b[i]&&k+j<=n;k+=a[i])
23                     c2[k+j]+=c1[j];
24             for(j=0;j<=n;j++)
25             {
26                 c1[j]=c2[j];
27                 c2[j]=0;
28             }
29         }
30         printf("%d\n",c1[n]);
31     }
32     return 0;
33 }

 

Holding Bin-Laden Captive! HDU1085

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

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 using namespace std;
 6 int c1[8005],c2[8005];
 7 int main()
 8 {
 9     int x,y,z,i,j,k,s;
10     while(scanf("%d%d%d",&x,&y,&z)!=EOF)
11     {
12         if(x==0&&y==0&&z==0)
13             break;
14         memset(c1,0,sizeof(c1));
15         memset(c2,0,sizeof(c2));
16         for(i=0;i<=x;i++)
17             c1[i]=1;
18             s=x+2*y;
19         for(j=0;j<=s;j++)
20             for(k=0;k+j<=s&&k<=2*y;k+=2)
21             c2[k+j]+=c1[j];
22         for(j=0;j<=s;j++)
23         {
24             c1[j]=c2[j];
25             c2[j]=0;
26         }
27         s+=5*z;
28         for(j=0;j<=s;j++)
29             for(k=0;k+j<=s&&k<=5*z;k+=5)
30             c2[k+j]+=c1[j];
31         for(j=0;j<=s;j++)
32         {
33             c1[j]=c2[j];
34             c2[j]=0;
35         }
36         for(i=1;i<=s;i++)
37         {
38             if(c1[i]==0)
39                 break;
40         }
41         printf("%d\n",i);
42     }
43 }

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

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<string.h>
 5 using namespace std;
 6 int c1[8005],c2[8005];
 7 int main()
 8 {
 9     int a,b,c,s,a1[3],b1[3],i,j,k;
10     a1[0]=1;a1[1]=2;a1[2]=5;
11     while(scanf("%d%d%d",&a,&b,&c)!=EOF)
12     {
13         if(a==0&&b==0&&c==0)
14             break;
15         s=a+2*b+c*5;
16         for(i=0;i<=s;i++)
17         {c1[i]=0;c2[i]=0;}
18         c1[0]=1;b1[0]=a;b1[1]=b;b1[2]=c;
19         for(i=0;i<3;i++)
20         {
21             for(j=0;j<=s;j++)
22                 for(k=0;k+j<=s&&k<=a1[i]*b1[i];k+=a1[i])
23                 c2[k+j]+=c1[j];
24             for(j=0;j<=s;j++)
25             {
26                 c1[j]=c2[j];
27                 c2[j]=0;
28             }
29         }
30         for(i=1;i<=s;i++)
31         {
32             if(c1[i]==0)
33                 break;
34         }
35         printf("%d\n",i);
36     }
37     return 0;
38 }

 

posted on 2013-07-31 22:18  ~~碾压机  阅读(182)  评论(0编辑  收藏  举报