NOJ [1356] Hey! Where Is My Sweets(╯▔皿▔)╯ 一个数拆分成最多m个数的不重复的方法数

  • [1356] Hey! Where Is My Sweets(╯▔皿▔)╯

  • 时间限制: 1000 ms 内存限制: 65535 K
  • 问题描述
  • There is a Horrible ghost story: TT robbbed all sweets from all NBUT ACMers, so she smirked:"Ho-Ho-Ho-Ho, He-He-He-He, Ha-Ha-Ha-Ha~". Then TT had S sweets and T bowls, she wanted to put all sweets in the bowls, sheallowed some bowls empty, so here comes the problem, how many different ways TT could put these sweets? One more rule, if there are 6 sweets and 3 bowls, shesaid 1,2,3 or 2,1,3 or 3,1,2 or 3,2,1 are the same, that means you can't treat these same ways as "different ways".
  • 输入
  • There are several cases, each line contains two integerss N and M, 1<=S<=60, 1<=T<= 50.
  • 输出
  • For each input, output the result in a single line.
  • 样例输入
  • 2 2
    5 3
  • 样例输出
  • 2
    5
    
  • 提示
  • 来源
  • 小白菜(Mr.Cai)
 题意:大致意思是指把 1个数 n分解成 多个数的和  且数的数量最多为t个   1 2 3  ,2 1 3 算作一种方法  问有多少中方法


思路:  母函数


#include<stdio.h>
#include<string.h>
int c1[61][51],c2[61][51]; // 前一个括号是指系数 后一个指硬币个数
int val[61];
int main()
{
	int i,j,k,l,n,m; 
	for(i=0;i<61;i++)
		val[i]=i;
	while(scanf("%d %d",&n,&m)!=EOF)// n是我们要组成的钱数 m是硬币最多的个数
	{
		memset(c1,0,sizeof(c1));
		memset(c2,0,sizeof(c2));
		for(i=0;i<=m;i++)
		{
			c1[i][i]=1;
		}
		for(i=2;i<=n;i++)//因为 硬币的价值可以为 1到n  所以共有n种硬币 所以要循环n次 第一次已算 
		{
			for(j=0;j<=n;j++)
				for(k=0;k+j<=n;k+=val[i])//次方最大为k+j所以要控制它小于n
					for(l=0;l+k/val[i]<=m;l++)
						c2[k+j][l+k/val[i]]+=c1[j][l];
					
					for(k=0;k<=n;k++)
						for(l=0;l<=m;l++)
						{
							c1[k][l]=c2[k][l];
							c2[k][l]=0;
						}
		}
		int sum=0;
		for(i=0;i<=m;i++)
			sum+=c1[n][i];
		printf("%d\n",sum);
	}
	return 0;
}






和这个题目神似

http://blog.csdn.net/hnust_xiehonghao/article/details/7857898

你可能感兴趣的:(NOJ [1356] Hey! Where Is My Sweets(╯▔皿▔)╯ 一个数拆分成最多m个数的不重复的方法数)