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

选课时间(题目已修改,注意读题)
Time Limit : 1000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 28   Accepted Submission(s) : 25
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
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 <stdio.h>

#define _MAX 50
int c1[_MAX], c2[_MAX];

typedef struct{
	int a; //学分
	int b; //有好多门
}COURSE;

COURSE c[10];

//
int cal(int n, int l)
{
	int i, j, k;
	for(i = 0; i <= n; i++)
	{
		c1[i] = 0;
		c2[i] = 0;
	}
	c1[0] = 1;
	for(i = 1; i <= l; i++)
	{
		for(j = 0; j <= n; j++)
		{
			for(k = 0; k <= c[i - 1].a * c[i - 1].b && k + j <= n; k += c[i - 1].a)
			{
				c2[j + k] += c1[j];
			}
		}
		for(j = 0; j <= n; j++)
		{
			c1[j] = c2[j];
			c2[j] = 0;
		}
	}
	return c1[n];
}
int main()
{
	int t, i, j;
	int n, k;
//	freopen("in.in", "r", stdin);
	scanf("%d", &t);
	for(i = 1; i <= t; i++)
	{
		scanf("%d%d", &n, &k);
		for(j = 0; j < k; j++)
			scanf("%d%d", &c[j].a, &c[j].b);
		printf("%d\n", cal(n, k));
	}
	return 0;
}

猜你喜欢

转载自609866532-qq-com.iteye.com/blog/1120466