选课时间(题目已修改,注意读题)
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2077 Accepted Submission(s): 1658
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门。
每组数据的第一行是两个整数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/*思路:母函数(注意一点就是相同学分的课没区别,则相同的学分只能保存一个),这里我用sqort 排序,再去掉想相同的学分的课,最后就是母函数模板。 */ #include<iostream> using namespace std; typedef struct infor { int score; int num ; }infor ; #define MAX 645 int c1[MAX] , c2[MAX] ; int cmp(void const *a,const void *b) { infor *c = (infor *)a ; infor *d = (infor *)b ; return c->score - d->score ; } int main(void) { int t ; cin >> t ; while( t--) { memset(c1 , 0 , sizeof(c1)); memset(c2 , 0 , sizeof(c2)); int i , j , k , n , m ; cin>> n >> m ; infor a[10] ; for( i = 0 ; i < m ; i ++) cin >> a[i].score >> a[i].num ; qsort(a,m,sizeof(a[0]),cmp); //按升序排序 k = 1 ; int sum = a[0].score * a[0].num ; for( i = 1 ; i < m ; i ++) //去掉相同学分的课 if(a[i-1].score != a[i].score){ a[k++] = a[i] ; sum +=a[i].score * a[i].num ; } m = k ; //更新课程的数目 for( i = 0 ; i <= a[0].num ; i ++) c1[i] = 1 ; for( i = 1 ; i < m ; i ++) { for( j = 0 ; j <= sum ; j ++) for( k = 0 ; k <= a[i].score * a[i].num ; k += a[i].score ) c2[j+k] += c1[j] ; for( j = 0 ; j <= sum ; j ++) { c1[j] = c2[j] ; c2[j] = 0 ; } } cout << c1[n] << endl; } return 0; }