HDU4979-A simple math problem.

来源:互联网 发布:当前数据连接不可用 编辑:程序博客网 时间:2024/06/03 18:47

A simple math problem.

                                                                    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
                                                                                              Total Submission(s): 435    Accepted Submission(s): 150


Problem Description
Dragon loves lottery, he will try his luck every week. One day, the lottery company brings out a new form of lottery called accumulated lottery. In a normal lottery, you pick 7 numbers from N numbers. You will get reward according to how many numbers you match. If you match all 7 numbers, you will get the top prize for 1 billion dollars!!! Unlike normal lottery, an M-accumulated lottery allows you to pick M numbers from N numbers. If M is big enough, this may significantly increase your possibility to win. (Of course it cost more…) 

Some people buy multiple accumulated lotteries to guarantee a higher possibility to get the top prize. Despite of this, it’s still not worthy to guarantee a top prize.Knowing this, Dragon changes his target to second tier prize. To get a second tier prize, you need to contain all of the R numbers with M numbers picked.Given N, M and R, Dragon wants to know how many M-accumulated lotteries he needs to buy, so that he can guarantee that he can get at least the second tier prize.
 

Input
The first line of input contains only one integer T, the number of test cases.

For each case, there’s a single line contains N, M and R(1<=R<=M<=N<=8).
 

Output
Each output should occupy one line. Each line should start with "Case #i: ", with i implying the case number. For each case, just output the result with no other leading or tailing spaces.
 

Sample Input
32 1 12 2 12 2 2
 

Sample Output
Case #1: 2Case #2: 1Case #3: 1
 

Author
BJTU
 

Source
2014 Multi-University Training Contest 10
 

题意:有n个号码,每张彩票是n中选M个号码的一个组合,中奖号码是n中选r个号码的一个组合,如果买的一张彩票m个号码完整覆盖r即中奖。给出n,m,r,问至少买多少彩票可以保证中奖

解题思路:这题需要舞蹈链重复覆盖打表才能通过,打表整整花了20分钟左右


#include <iostream>      #include <cstdio>      #include <cstring>      #include <string>      #include <algorithm>      #include <cctype>      #include <map>      #include <cmath>      #include <set>      #include <stack>      #include <queue>      #include <vector>      #include <bitset>      #include <functional>      using namespace std;#define LL long long      const int INF = 0x3f3f3f3f;const int maxn = 300005;/*int n, m, R, x, y, tot1, tot2;vector<int>g[10];struct DLX{int L[maxn], R[maxn], U[maxn], D[maxn];int row[maxn], col[maxn], sum[maxn], ans[maxn];int n, m, num, cnt;int vis[maxn];void add(int k, int l, int r, int u, int d, int x, int y){L[k] = l;   R[k] = r;   U[k] = u;D[k] = d;   row[k] = x;  col[k] = y;}void reset(int n, int m){num = 0x7FFFFFFF;this->n = n;   this->m = m;for (int i = 0; i <= m; i++){add(i, i - 1, i + 1, i, i, 0, i);sum[i] = 0;}L[0] = m, R[m] = 0, cnt = m + 1;}void insert(int x, int y){int temp = cnt - 1;if (row[temp] != x){add(cnt, cnt, cnt, U[y], y, x, y);U[D[cnt]] = cnt; D[U[cnt]] = cnt;}else{add(cnt, temp, R[temp], U[y], y, x, y);R[L[cnt]] = cnt; L[R[cnt]] = cnt;U[D[cnt]] = cnt; D[U[cnt]] = cnt;}sum[y]++, cnt++;}void Remove(int k){for (int i = D[k]; i != k; i = D[i]){L[R[i]] = L[i];R[L[i]] = R[i];}}void Resume(int k){for (int i = U[k]; i != k; i = U[i]) L[R[i]] = R[L[i]] = i;}int A(){int dis = 0;for (int i = R[0]; i != 0; i = R[i]) vis[i] = 0;for (int i = R[0]; i != 0; i = R[i])if (!vis[i]){dis++, vis[i] = 1;for (int j = D[i]; j != i; j = D[j])for (int k = R[j]; k != j; k = R[k])vis[col[k]] = 1;}return dis;}void Dfs(int k){if (!R[0]) { num = min(num, k); return ; }else if (k + A() < num){int now = R[0];for (int i = R[0]; i != 0; i = R[i])if (sum[now] > sum[i]) now = i;for (int i = D[now]; i != now; i = D[i]){ans[k] = row[i];Remove(i);for (int j = R[i]; j != i; j = R[j]) Remove(j);Dfs(k + 1);for (int j = L[i]; j != i; j = L[j]) Resume(j);Resume(i);}}}}dlx;int main(){freopen("output.txt", "w", stdout);for (int n = 1; n <= 8; n++){for (int k = 1; k <= n; k++) g[k].clear();for (int k = 1; k < (1 << n); k++){int sum = 0;for (int p = 0; p < n; p++)if (k&(1 << p)) sum++;g[sum].push_back(k);}for (int i = 1; i <= n; i++) sort(g[i].begin(), g[i].end());for (int m = 1; m <= n; m++){for (int R = 1; R <= m; R++){tot1 = g[R].size(), tot2 = g[m].size();dlx.reset(tot2, tot1);for (int i = 0; i < tot2; i++)for (int j = 0; j < tot1; j++)if ((g[m][i] | g[R][j]) == g[m][i])dlx.insert(i + 1, j + 1);dlx.Dfs(0);printf("%d ", dlx.num);}printf("\n");}printf("\n\n");}return 0;}*/int ans[10][10][10]={{{1}},{{2},{1, 1}},{{3},{2,3},{1, 1, 1}},{{4},{2, 6},{2, 3, 4},{1, 1, 1, 1}},{{5},{3, 10},{2, 4, 10},{2, 3, 4, 5},{1, 1, 1, 1, 1}},{{6},{3, 15},{2, 6, 20},{2, 3, 6, 15},{2, 3, 4, 5, 6},{1, 1, 1, 1, 1, 1}},{{7},{4, 21},{3, 7, 35},{2, 5, 12, 35},{2, 3, 5, 9, 21},{2, 3, 4, 5, 6, 7},{1, 1, 1, 1, 1, 1, 1}},{{8},{4, 28},{3, 11, 56},{2, 6, 14, 70},{2, 4, 8, 20, 56},{2, 3, 4, 7, 12, 28},{2, 3, 4, 5, 6, 7, 8},{1, 1, 1, 1, 1, 1, 1, 1}}};int n, m, R;int main(){int t, cas = 0;scanf("%d", &t);while (t--){scanf("%d%d%d", &n, &m, &R);printf("Case #%d: %d\n", ++cas, ans[n - 1][m - 1][R - 1]);}return 0;}