Happy Matt Friends

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

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 first 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
 
Recommend
liuyiding
 
这题比赛时候居然没有做出来呜呜呜,我对dp的学习路线让人怀疑。。。。
 
接下来分析一下这个题
 
本题大意:给定n个数,让你在n个数字中选择任意多个数字,使得他们的异或和 >= m。
你不知道某些数字选还是不选,多选或者少选都可能多一种方案,看数据范围数字总共不到40个,
最大值在1e6以内,所以这些值异或之后的最大值也不超过1 << 20,所以应该就要想到一个数字
选还是不选应该是最重要的,他选了之后对于已经选过的值的影响的记录也是必要的,所以肯定要
知道某个值选不选?然后还要把异或之后的值记录下来,记录的话肯定是需要一维记录了,我们想到可以把这些数可以异或得到的所有结果记录下来,然后查询大于等于m的个数有多少个即可。所以索性我们就假设dp[ i ][ j ]为前i个数,选择一些异或起来异或和为 j 的方案数,这样我们很容易就可以得到递推方程dp[ i ][ j ] = dp[i - 1][j ^ a[ i ]] + dp[i - 1][ j ],那就是一个数选或者不选,有两种情况,方法数相加。
 
哦,一看就知道要开4 * 1e7的long long的数组,写出方程后应该可以想到数组是可以滚动的,因为
对于每前i个的计算只需要前i - 1 个数的状态,所以我们索性就开一个dp[ 2 ][ maxn ]的数组,用 & 来滚动数组就行了。哦,具体见代码。
 
 /*
本题思路:用dp[i][j]表示前i个数可以凑出数字j的方法数目。
dp[i][j] = dp[i - 1][j ^ a[i]] + dp[i - 1][j];
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = + , maxm = << ;
int n, m; typedef long long ll; int a[maxn]; ll dp[][maxm]; int main() {
int t, _case = ;
scanf("%d", &t);
while(t --) {
memset(dp, , sizeof dp);
scanf("%d %d", &n, &m);
for(int i = ; i <= n; i ++) {
scanf("%d", &a[i]);
}
/*
dp[0][0] = 1;
for(int i = 1; i <= n; i ++) {
for(int j = 0; j < maxm; j ++) {
dp[i][j] = dp[i - 1][j ^ a[i]] + dp[i - 1][j];
}
}
*/
dp[][] = ;
for(int i = ; i <= n; i ++) {
for(int j = ; j < maxm; j ++) {
dp[i & ][j] = dp[i - & ][j ^ a[i]] + dp[i - & ][j];
}
}
ll ans = ;
for(int i = m; i < maxm; i ++) {
ans += dp[n & ][i];
}
printf("Case #%d: %lld\n", ++ _case, ans);
}
return ;
}

2014年北京 happy matt friends(dp + 滚动数组优化)的更多相关文章

  1. HDU_1024.MaxSumPlusPlus(基础DP + 滚动数组优化讲解)

    这道题打破了我常规的做题思路,因为这是我刚开始训练DP,感觉这道题目好晕眼呀,emm其实就是感觉自己是真的菜...... 为什么说打破了我的做题思路呢,因为我平时看题解都是在已经AC或者完全不懂的情况 ...

  2. [BZOJ1044][HAOI2008]木棍分割 二分 + 单调队列优化dp + 滚动数组优化dp

    Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...

  3. LG3004 「USACO2010DEC」Treasure Chest 区间DP+滚动数组优化

    问题描述 LG3004 题解 把拿走的过程反向,看做添加的过程,于是很显然的区间DP模型. 设\(opt_{i,j}\)代表区间\([i,j]\)中Bessie可以获得的最大值,显然有 \[opt_{ ...

  4. poj1159 dp(滚动数组优化)

    H - 简单dp 例题扩展 Crawling in process... Crawling failed Time Limit:3000MS     Memory Limit:65536KB     ...

  5. 51Nod 1084 矩阵取数问题 V2 双线程DP 滚动数组优化

    基准时间限制:2 秒 空间限制:131072 KB  一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,先从左上走到右下,再从右下走到左上.第1遍时只能向下和向右走,第2遍时只能向 ...

  6. POJ 3666 Making the Grade (DP滚动数组)

    题意:农夫约翰想修一条尽量平缓的路,路的每一段海拔是A[i],修理后是B[i],花费|A[i] – B[i]|,求最小花费.(数据有问题,代码只是单调递增的情况) #include <stdio ...

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

    题目链接:HDU 5119 Problem Description Matt has N friends. They are playing a game together. Each of Matt ...

  8. BZOJ-1925 地精部落 烧脑DP+滚动数组

    1925: [Sdoi2010]地精部落 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1053 Solved: 633 [Submit][Status ...

  9. HDU 1024 Max Sum Plus Plus --- dp+滚动数组

    HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...

随机推荐

  1. js callback回调的一种写法

    getLocation.cityname(latitude, longitude, function (data1) { SetCityCallBack(data1); }); 定义方法: var g ...

  2. CSS 按钮

    总结有关按钮的各种样式 ㈠基本按钮样式 看一下没有进行css样式设计时按钮的样子与进行样式设计的按钮样子 <!DOCTYPE html> <html> <head> ...

  3. 【CF963C】Cutting Rectangle(数论,构造,map)

    题意: 思路:考虑构造最小的单位矩形然后平铺 单位矩形中每种矩形的数量可以根据比例算出来,为c[i]/d,其中d是所有c[i]的gcd,如果能构造成功答案即为d的因子个数 考虑如果要将两种矩形放在同一 ...

  4. Python实用黑科技——找出最大/最小的n个元素

    需求: 快速的获取一个列表中最大/最小的n个元素. 方法: 最简便的方法是使用heapq模组的两个方法nlargest()和nsmallest(),例如: In [1]: import heapqIn ...

  5. openwrt python27库的选择和库的大小

    < > micropython................................................. Micro Python < > microp ...

  6. JavaWeb_初识监听器Listener

    监听器(listener):对项目起到监听的作用,它能感知到包括request(请求域),session(会话域)和applicaiton(应用程序)的初始化和属性的变化 监听器是Servlet规范中 ...

  7. [BZOJ3786] 星系探索(括号序列+Splay)

    3786: 星系探索 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 2191  Solved: 644[Submit][Status][Discuss ...

  8. C++入门经典-例3.24-找图书的位置

    1:运行代码: // 3.24.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> usin ...

  9. Spark学习(二)——RDD的设计与运行原理

    Spark的核心是建立在统一的抽象RDD之上,使得Spark的各个组件可以无缝进行集成,在同一个应用程序中完成大数据计算任务.RDD的设计理念源自AMP实验室发表的论文<Resilient Di ...

  10. Centos 6.5 Multipath 初始配置

    # This is a basic configuration file with some examples, for device mapper # multipath. # For a comp ...