母函数题目

遇到一个问题,学习一下母函数。

这些题目用DP,递推都可以解决。

http://acm.hut.edu.cn/?p=277这里有篇讲解不错。

生成函数主要为两种,普通型以及指数型。

普通型的一般求解就是模拟多项式系数求解。

而指数型一般数量级很大,需要通过级数化简。比较坑,要有不错的高数功底。

HDU 1085 Holding Bin-Laden Captive!

http://acm.hdu.edu.cn/showproblem.php?pid=1085

有币值1,2,5的硬币若干,问你最少的不能组成的币值为多少。

(1+x+x^2+x^3……x^c1)*(1+x^2+x^4……x^2*c2)*(1+x^5+x^10……x^5*c3)

接下来就是求出每项的系数。模拟一下就行了,两项两项

[cpp]  view plain copy
  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<cstring>  
  4. #include<queue>  
  5. #include<vector>  
  6. #include<cmath>  
  7. #define LL  long long  
  8. #define MOD 29  
  9. #define eps 1e-6  
  10. #define N 100010  
  11. #define zero(a)  fabs(a)<eps  
  12. using namespace std;  
  13. int val[3]={1,2,5},cnt[3];  
  14. int c1[10005],c2[10005];  
  15. int main(){  
  16.     while(scanf("%d%d%d",&cnt[0],&cnt[1],&cnt[2])!=EOF&&cnt[0]+cnt[1]+cnt[2]){  
  17.         int mmax=0;  
  18.         for(int i=0;i<3;i++)  
  19.             mmax+=cnt[i]*val[i];  
  20.         memset(c1,0,sizeof(c1));  
  21.         memset(c2,0,sizeof(c2));  
  22.         for(int i=0;i<=cnt[0];i++)  
  23.             c1[i]=1;  
  24.         for(int i=1;i<3;i++){  
  25.             for(int j=0;j<=mmax;j++)  
  26.                 for(int k=0;k<=val[i]*cnt[i];k+=val[i])  
  27.                     if(j+k<=mmax&&c1[j])  
  28.                          c2[j+k]=c1[j];  
  29.             for(int j=0;j<=mmax;j++){  
  30.                 c1[j]=c2[j];  
  31.                 c2[j]=0;  
  32.             }  
  33.         }  
  34.         int i;  
  35.         for(i=0;i<=mmax+1;i++)  
  36.             if(c1[i]==0)  
  37.                 break;  
  38.         printf("%d\n",i);  
  39.     }  
  40.     return 0;  
  41. }  

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

http://acm.hdu.edu.cn/showproblem.php?pid=2079

同样 是每种物品有一点的价值和一点的数量。


 

UESTC 1726 整数划分

 

http://acm.uestc.edu.cn/problem.php?pid=1726 


HDU 1171 Big Event in HDU

http://acm.hdu.edu.cn/showproblem.php?pid=1171

背包问题,同样是物品价值和数量。构造普通生成函数


HDU 1028 Ignatius and the Princess III

http://acm.hdu.edu.cn/showproblem.php?pid=1028

整数划分问题,相当于有1,2,3……价值的物品无数。然后便是一样的构造


HDU 1398 Square Coins

http://acm.hdu.edu.cn/showproblem.php?pid=1398

有物品价值1,4,9,16……平方数的物品无数。


HDU 2082 找单词

http://acm.hdu.edu.cn/showproblem.php?pid=2082

像这类题目,直接要把上限掐断。提高效率


HDU 2069 Coin Change

http://acm.hdu.edu.cn/showproblem.php?pid=2069

找硬币问题,有个限制条件,就是总数不能超过100。可以有很多解法,可以将母函数变形,加一维表示数量

  
  
  
  
[cpp] view plain copy
  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<cstring>  
  4. #include<queue>  
  5. #include<vector>  
  6. #include<cmath>  
  7. #define LL  long long  
  8. #define MOD 29  
  9. #define eps 1e-6  
  10. #define N 100010  
  11. #define zero(a)  fabs(a)<eps  
  12. using namespace std;  
  13. int val[5]={1,5,10,25,50};  
  14. int c1[255][105]={0},c2[255][105]={0};  
  15. int cnt[30];  
  16. int main(){  
  17.     for(int i=0;i<=100;i++)  
  18.         c1[i][i]=1;  
  19.     for(int i=1;i<5;i++){  
  20.         for(int j=0;j<=250;j++)  
  21.             for(int k=0;k+j<=250;k+=val[i])  
  22.                 for(int r=0;r+k/val[i]<=100;r++)  
  23.                     c2[j+k][r+k/val[i]]+=c1[j][r];  
  24.         for(int j=0;j<=250;j++)  
  25.             for(int k=0;k<=100;k++){  
  26.                 c1[j][k]=c2[j][k];  
  27.                 c2[j][k]=0;  
  28.             }  
  29.     }  
  30.     int n;  
  31.     while(scanf("%d",&n)!=EOF){  
  32.         int ans=0;  
  33.         for(int i=0;i<=100;i++)  
  34.             ans+=c1[n][i];  
  35.         printf("%d\n",ans);  
  36.     }  
  37.     return 0;  
  38. }  
HDU 1709 The Balance
http://acm.hdu.edu.cn/showproblem.php?pid=1709
杠杆问题,也就是因为有左右之分,价值有正负。为了避免下标出现负的,统一加上某个值,可以是价值总数。
 
 
HDU 2065 "红色病毒"问题
http://acm.hdu.edu.cn/showproblem.php?pid=2065
POJ 3734 Blocks
http://poj.org/problem?id=3734
这两题是指数型母函数,需要用到泰勒级数等数学知识。
详见这里http://blog.csdn.net/acm_cxlove/article/details/7831009

你可能感兴趣的:(母函数题目)