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

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

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


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
 
 
 1 /*
 2     代码一  ---- WA
 3     原因:题目中明确规定了  “一样学分的课没区别”  悲剧了,写的时候没考虑
 4 
 5 #include <iostream>
 6 #include <cstdio>
 7 
 8 using namespace std;
 9 
10 int score[100];
11 int res;
12 void DFS(int cur, int sum, int num, int n)
13 {
14     if(sum > n || cur >= num)
15         return;
16     if(sum == n)
17     {
18         ++res;
19         return;
20     }
21     DFS(cur + 1, sum + score[cur], num, n);
22     DFS(cur + 1, sum, num, n);
23 }
24 
25 int main()
26 {
27     int T, n, k, a, b;
28     scanf("%d", &T);
29     while(T--)
30     {
31         res = 0;
32     //    memset(score, 0, sizeof(score));
33         scanf("%d%d", &n, &k);
34         int num = 0;
35         while(k--)
36         {
37             scanf("%d%d", &a, &b);
38             while(a--)
39                 score[num++] = b;
40         }
41         DFS(0, 0, num, n);
42         printf("%d\n", res);
43     }
44     return 0;
45 }
46 */
47 
48 
49 // 代码二:  --- AC
50 #include <iostream>
51 #include <cstdio>
52 
53 using namespace std;
54 
55 int score[10];
56 int res;
57 
58 //从 学分为 1 的课程到学分为 max 的课程依次 DFS,直到修够 n 学分,或者超出限制为止
59 void DFS(int cur, int sum, int max, int n)    //cur 表示当前所选学分为 cur 的课程
60 {                               //sum  保存已经修的学分总数
61     if(sum == n)   // 注意这个 if 不能写在 下边的 if 后边 ,否则当选择最后一门课正好满足条件时会直接跳出,结果数会遗漏
62     {
63         ++res;
64         return;
65     }
66     if(sum > n || cur > max)
67         return;
68     if(score[cur] == 0)    //  表示不存在学分为 cur 的课程
69     {
70         DFS(cur + 1, sum, max, n);
71         return;
72     }
73     for(int i = 0; i <= score[cur]; ++i)
74         DFS(cur + 1, sum + i * cur, max, n);
75 }
76 
77 int main()
78 {
79     int T, n, k, a, b;
80     scanf("%d", &T);
81     while(T--)
82     {
83         res = 0;
84         memset(score, 0, sizeof(score));
85         scanf("%d%d", &n, &k);
86         int max = 0;
87         while(k--)
88         {
89             scanf("%d%d", &a, &b);
90             score[a] = b;      //学分为 a 的课有 b 门
91             if(max < a)
92                 max = a;
93         }
94         DFS(1, 0, max, n);
95         printf("%d\n", res);
96     }
97     return 0;
98 }

 代码三:-------复习回顾

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 
 5 using namespace std;
 6 
 7 int cnt[10];  // cnt[i] 表示学分为i的课的数量 
 8 int ans, score;
 9 
10 void DFS(int sum, int cur)
11 {
12     if(sum == score)
13     {
14         ++ans;
15         return;
16     }
17     if(sum > score || cur > 8)//学分最多是 8 分 
18         return;
19     for(int i = 0; i <= cnt[cur]; ++i)
20         DFS(sum+cur*i, cur+1);
21 }
22 
23 int main()
24 {
25     int T, k, a, b;
26     scanf("%d", &T);
27     while(T--)
28     {
29         scanf("%d%d", &score, &k);
30         memset(cnt, 0, sizeof(cnt));
31         ans = 0; 
32         for(int i = 0; i < k; ++i)
33         {
34             scanf("%d%d", &a, &b);
35             cnt[a] = b; 
36         } 
37         DFS(0, 0); 
38         printf("%d\n", ans);
39     }
40     return 0;
41 }
功不成,身已退
原文地址:https://www.cnblogs.com/dongsheng/p/2797700.html