首先给出基本的模板:也就是以前所说的公式(不是什么很难的东西)
#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 ",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 ",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 ",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 ",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 ",i); 36 } 37 return 0; 38 }