Happy Matt Friends(DP)

Happy Matt Friends

Time Limit: 6000/6000 MS (Java/Others)    Memory Limit: 510000/510000 K (Java/Others)
Total Submission(s): 3700    Accepted Submission(s): 1407

Problem Description

Matt has N friends. They are playing a game together.

Each of Matt’s friends has a magic number. In the game, Matt selects some (could be zero) of his friends. If the xor (exclusive-or) sum of the selected friends’magic numbers is no less than M , Matt wins.

Matt wants to know the number of ways to win.

Input

The first line contains only one integer T , which indicates the number of test cases.

For each test case, the first line contains two integers N, M (1 ≤ N ≤ 40, 0 ≤ M ≤ 106).

In the second line, there are N integers ki (0 ≤ ki ≤ 106), indicating the i-th friend’s magic number.

Output

For each test case, output a single line “Case #x: y”, where x is the case number (starting from 1) and y indicates the number of ways where Matt can win.

Sample Input

2

3 2

1 2 3

3 3

1 2 3

Sample Output

Case #1: 4

Case #2: 2

Hint

In the ?rst sample, Matt can win by selecting:
friend with number 1 and friend with number 2. The xor sum is 3.
friend with number 1 and friend with number 3. The xor sum is 2.
friend with number 2. The xor sum is 2.
friend with number 3. The xor sum is 3. Hence, the answer is 4.

Source

2014ACM/ICPC亚洲区北京站-重现赛(感谢北师和上交)

//题意:第一行T,然后是2个整数 n,m ,然后给出n个数字,问这些数字任意组合,求异或和大于等于m的组合个数

t题解:暴力DP即可 dp[i][j] 为前 i 个数可以组成异或和等于 j 的个数

dp[i][j] = dp [i-1][j] + dp[i-1][j^num[i]]

可以滚动,可以不滚动

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5 #define LL long long
 6 #define MX 1000005
 7
 8 int Scan() {    //输入外挂
 9     int res = 0, flag = 0;
10     char ch;
11     if((ch = getchar()) == ‘-‘) flag = 1;
12     else if(ch >= ‘0‘ && ch <= ‘9‘) res = ch - ‘0‘;
13     while((ch = getchar()) >= ‘0‘ && ch <= ‘9‘)
14         res = res * 10 + (ch - ‘0‘);
15     return flag ? -res : res;
16 }
17
18 void Out(int a) {    //输出外挂
19     if(a < 0) { putchar(‘-‘); a = -a; }
20     if(a >= 10) Out(a / 10);
21     putchar(a % 10 + ‘0‘);
22 }
23
24 int n,m;
25 int dp[2][1<<21]; // i 个数异或和为 j 个数
26 int num[MX];
27
28 int main()
29 {
30     int T;
31     cin>>T;
32     for(int cnt=1;cnt<=T;cnt++)
33     {
34         n=Scan(),m=Scan();
35         for (int i=1;i<=n;i++)
36             scanf("%d",&num[i]);
37         memset(dp,0,sizeof(dp));
38         dp[0][0]=1;
39         for (int i=1;i<=n;i++)
40         {
41             for (int j=0;j<MX;j++)
42             {
43                 dp[i&1][j]=dp[(i-1)&1][j]+dp[(i-1)&1][j^num[i]];
44             }
45         }
46         LL ans =0;
47         for (int i=m;i<MX;i++)
48             ans += dp[n&1][i];
49         printf("Case #%d: %I64d\n",cnt,ans);
50     }
51     return 0;
52 }

时间: 2024-10-12 09:04:52

Happy Matt Friends(DP)的相关文章

HDOJ 5119 Happy Matt Friends DP

N*M暴力DP.... Happy Matt Friends Time Limit: 6000/6000 MS (Java/Others)    Memory Limit: 510000/510000 K (Java/Others) Total Submission(s): 82    Accepted Submission(s): 34 Problem Description Matt has N friends. They are playing a game together. Each

HDU 5119 Happy Matt Friends(DP)

题目链接:传送门 题意: 给定n个数,求从中选出任意个数异或起来值大于m的方案数. 分析: 动态规划,设dp[i][j] 表示第几次选第i个数的时候异或起来 值为j的方案数.dp[i][j^a[i]]+=dp[i][j];但是对空间有要求 我们可以用滚动数组来写. 代码如下: #include <iostream> #include <cstring> #include <cstdio> using namespace std; const int maxn = 1&l

HDU 5119 Happy Matt Friends(dp+位运算)

题意:给定n个数,从中分别取出0个,1个,2个...n个,并把他们异或起来,求大于m个总的取法. 思路:dp,背包思想,考虑第i个数,取或者不取,dp[i][j]表示在第i个数时,异或值为j的所有取法.dp[i][j] = dp[i - 1][j] + dp[i - 1][j ^ a[i]]); 其中dp[i - 1][j]表示不取第i个数,dp[i - 1][j & a[i]]表示取第i个数,由于40比较大,所以用滚动数组优化,后一个状态需要前一个来推导,而和前一个之前的所有的没有关系,所以之

HDU--5119Happy Matt Friends+dp

其实还是穷举子集类的dp,一般这种dp我们只需要用一个一维的滚动数组就可以了,但是这个题目状态转移的时候不但可能向后还有可能向前,所以这次得用二维数组. 状态方程 dp[i][j]=dp[i-1][j]+dp[i-1][j^num[i]],分别表示第i个数不取和第i个数取情况下状态. 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define maxn

HDU 5119 Happy Matt Friends(DP || 高斯消元)

题目链接 题意 : 给你n个数,让你从中挑K个数(K<=n)使得这k个数异或的和小于m,问你有多少种异或方式满足这个条件. 思路 : 正解据说是高斯消元.这里用DP做的,类似于背包,枚举的是异或的和,给定的数你可以选择放或者不放,dp[i][j]代表的是前 i 个数中选择k个异或的和为j. 1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #define LL long long

HDU 5119 Happy Matt Friends(简单二维dp)

题意不再说了,就是一个二维的dp,维持取最大值是多少. Happy Matt Friends Time Limit: 6000/6000 MS (Java/Others)    Memory Limit: 510000/510000 K (Java/Others) Total Submission(s): 608    Accepted Submission(s): 229 Problem Description Matt has N friends. They are playing a ga

hustwinterC - Happy Matt Friends(dp解法)

Description Matt has N friends. They are playing a game together. Each of Matt’s friends has a magic number. In the game, Matt selects some (could be zero) of his friends. If the xor (exclusive-or) sum of the selected friends’magic numbers is no less

HDU 5119 Happy Matt Friends (背包DP + 滚动数组)

题目链接:HDU 5119 Problem Description Matt has N friends. They are playing a game together. Each of Matt's friends has a magic number. In the game, Matt selects some (could be zero) of his friends. If the xor (exclusive-or) sum of the selected friends'ma

HDU 5119 Happy Matt Friends(DP)

求解方案数的简单DP,比赛时没有往DP上想,思维比较局限. 状态转移很好写,类似于背包,我用记忆化搜索写的容易写,但是效率比较低,还占内存,读者可以改成递推式,还可以改成滚动数组,因为每一层的状态只用到它上一层的状态 . 细节参见代码: #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<map