hdu 2079 选课时间(题目已修改,注意读题) 母函数

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

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

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3434    Accepted Submission(s): 2704


Problem Description
又到了选课的时间了,xhd看着选课表发呆,为了想让下一学期好过点,他想知道学n个学分共有多少组合。你来帮帮他吧。(xhd认为一样学分的课没区别)
 

Input
输入数据的第一行是一个数据T,表示有T组数据。
每组数据的第一行是两个整数n(1 <= n <= 40),k(1 <= k <= 8)。
接着有k行,每行有两个整数a(1 <= a <= 8),b(1 <= b <= 10),表示学分为a的课有b门。
 

Output
对于每组输入数据,输出一个整数,表示学n个学分的组合数。
 

Sample Input
  
  
2 2 2 1 2 2 1 40 8 1 1 2 2 3 2 4 2 5 8 6 9 7 6 8 8
 

Sample Output
  
  
2 445
 


突然顿悟了母函数。其实就是模拟来的。第一个东西取几个 的状态 先弄出来,然后接下来就是有新的东西,然后就是新的放一个或者多个  更新进去,然后注意别超过最大值就行了。


//整数拆分模板
#include <iostream>
using namespace std;
const int lmax=1000;
//c1是用来存放展开式的系数的,而c2则是用来计算时保存的,
//他是用下标来控制每一项的位置,比如 c2[3] 就是 x^3 的系数。 
//用c1保存,然后在计算时用c2来保存变化的值。 
int c1[lmax+1],c2[lmax+1];
int aa[20],bb[20];
int main()
{
	int n;
	int sum; 
	int t;
	scanf("%d",&t);
	while (t--)
	{ 
		scanf ("%d%d",&sum,&n);
		for(int i=1;i<=n;i++)
		{
			scanf("%d%d",aa+i,bb+i);
		}
		for(int i=0; i<=sum; i++ )
		{
			c1[i]=0;
			c2[i]=0;
		}
		if(n)
		for(int i=0;i<=bb[1];i++)
		{
			if(aa[1]*i<=sum)
				c1[aa[1]*i]=1;
		} 
		for (int i=2; i<=n; i++)
		{
			for (int j=0; j<=sum; j++ )
			{
				for (int k=0; k<=bb[i]; k++ )
				{ 
					if(j+k*aa[i]<=sum)
					c2[j+k*aa[i]]+=c1[j];
				}		
			}
			for (int j=0; j<=sum; j++ )
			{
				c1[j] = c2[j] ;
				c2[j] = 0 ;
			}
		}
		printf ("%d\n",c1[sum]);
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值