用母函数解组合问题
来源:互联网 发布:网络教育本科二学历 编辑:程序博客网 时间:2024/06/14 01:16
1.引言
母函数是解组合问题的工具,关于母函数的介绍参考百度百科:http://baike.baidu.com/view/2415279.htm
杭电OJ平台与母函数相关的编程题有1028、1085、1171、1398
北大OJ平台与母函数相关的编程题有1664
2.HD1028
这道题的意思就是将一个数n,分为1,2,3…,n的组合,允许重复,求组合的种数。
#include<stdio.h>int a1[121],a2[121];//系数数组int main(){ int i,j,k,n; while(scanf("%d",&n)!=EOF) { for(i=0;i<=n;i++)/*初始化第一个函数,把第一个函数的系数都赋值为1,(1+x^a1+x^2a1+x^3a1+……)*/{a1[i]=1;a2[i]=0;}for(i=2;i<=n;++i) //求第i个表达式(1+x^ai+x^2ai+x^3ai+...) { for(j=0;j<=n;++j)//j 从0到n遍历,这里j就是(前面i个表达式累乘的表达式)里第j个变量, for(k=0;k+j<=n;k+=i)// k表示的是第j个指数,所以k每次增i(因为第i个表达式的增量是i)。 a2[j+k]+=a1[j]; // 每次前i个表达式累乘求完后都把中间变量a2赋值给a1 for(j=0;j<=n;++j) { a1[j]=a2[j]; a2[j]=0;} } printf("%d\n",a1[n]); } return 0;}
3.PKU1664
这道题的意思就是将n个一样的苹果放入,m个一样的盘子,盘子允许空。问有多少种放法。
#include <iostream>using namespace std;int main(){int row,i;cin >> row;int *p=new int[row];for(i=0;i<row;i++){int apples,dishes;int j,k,s;cin >> apples;cin >> dishes;int *p1=new int[apples+1];int *p2=new int[apples+1];for(j=0;j<=apples;j++){p1[j]=1;p2[j]=0;}for (j=2;j<=dishes;j++){for(k=0;k<=apples;k++)for (s=0;s+k<=apples;s+=j)p2[s+k]+=p1[k];for (k=0;k<=apples;k++){p1[k]=p2[k];p2[k]=0;}}p[i]=p1[apples];delete [] p1;delete [] p2;}for (i=0;i<row;i++)cout << p[i]<<endl;delete [] p;return 0;}
4.HD1085
这一题的意思是有num1个1,num2个2,num5个5,问有这些数字(numX(X=1,2,5)是个数上限),不能组合出的最小值。
int main(){int number[3]={1,2,5};int num[3]={0}; //因为循环中要用到循环数i来索引,所以定义为数组int i,j,k;while (scanf("%d %d %d",&num[0],&num[1],&num[2]),num[0]||num[1]||num[2]){int max=num[0]+2*num[1]+5*num[2];//最大值int *p=(int*)calloc(max+1,sizeof(int));//包括0所以max+1int *q=(int*)calloc(max+1,sizeof(int));//调用calloc是因为calloc初始化为0,malloc不初始化for (i=0;i<=num[0];i++) //初始化第一组{p[i]=1;q[i]=0;}int array_size=num[0];//循环次数for(i=2;i<=NUM;i++) //一共3个数{for (j=0;j<=array_size;j++)for (k=0;k+j<=array_size+number[i-1]*num[i-1];k+=number[i-1])q[k+j]+=p[j];array_size+=number[i-1]*num[i-1];for (j=0;j<=array_size;j++){p[j]=q[j];q[j]=0;}}for (i=0;i<=max;i++){if (p[i]==0)break;}if (i==max)printf("%d\n",max+1);elseprintf("%d\n",i);free(p);free(q);}return 0;}
5.HD1398
这题的意思是有17种硬币,面值分别是1至17的平方,输入一个数(不大于300),求组成这个数的硬币种数。
#include <iostream>using namespace std;int const coins[18]={0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289};//0作为哨兵int p[301],q[301]={0};int main(){int i,j,k;int sum,kinds;while(cin>>sum,sum!=0){for(i=0;i<=sum;i++)p[i]=1;for(kinds=1;kinds<=17;kinds++)if (kinds*kinds>sum) break;for (i=2;i<kinds;i++) //剪枝,可能有多少种类的硬币{for (j=0;j<=sum;j++)for (k=0;k+j<=sum;k+=coins[i])q[k+j]+=p[j];for (j=0;j<=sum;j++){p[j]=q[j];q[j]=0;}}cout<<p[sum]<<endl;}return 0;}
- 用母函数解组合问题
- hdu1085(母函数解有限个硬币组合问题)
- 组合数学之母函数问题
- 母函数模板---解决组合数问题
- 组合数学-母函数
- 组合问题 之 函数的NULL参数
- SG函数与组合博弈问题
- 母函数算法---组合数学
- 组合数学之 母函数
- 组合数与母函数
- poj1664 组合数学 母函数
- 用母函数证明一个基本的组合公式
- 用母函数证明另一个基础的组合公式
- POJ-4004:数字组合(用位移方法解组合数问题,Java版)
- 用python求解组合问题
- 函数组合
- 组合问题!
- 组合问题
- Spinner 讲解
- 枚举+搜索 hdu-4431-Mahjong
- JAVA实现邮件群发
- GDB调试--转自陈皓
- hdu 1251 统计难题
- 用母函数解组合问题
- hdu(3835)
- Ubuntu 12.04.2 x64 安装go语言
- 短信模块开发 tpdu格式(一)
- 循环队列
- 短信模块开发 tpdu格式(二)
- POJ3767----I Wanna Go Home
- 转载 oracle 设UTF8
- 8月18日 星期日 要做的事情比较多 理顺一下