HDU
来源:互联网 发布:linux改名命令 编辑:程序博客网 时间:2024/06/05 02:07
题目意思是:给定 n 个数,求所有子集的异或和 大于等于 m 的子集个数有多少
首先想到的是枚举子集,但是 n 最大是 40 ,2 的 40 次方没法实现
然而给定 的每个数 a [ i ] 最大范围是 1e6 ,二进制下不会超过 19 位,所以任意多个 a [ i ] 进行异或,其answer 都是小于 2进制下 20位的这个数 ------ (2 << 20)
然后开滚动数组 dp [ i ] [ j ] 表示前 i 个数中,异或和为 j 的个数
注意:题目中又说可以不选,所以初始化的时候 dp [ 1 ] [ 0 ] = 1; dp [ 1 ] [ a[i] ] = 1;
递推式就很容易了,见代码中:
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <cmath>#include <set>#include <map>#include <stack>#include <queue>#include <ctype.h>#include <vector>#include <algorithm>#include <sstream>#define PI acos(-1.0)#define in freopen("in.txt", "r", stdin)#define out freopen("out.txt", "w", stdout)using namespace std;typedef long long ll;const int maxn = (1<<20) + 7, INF = 0x3f3f3f3f, mod = 1e9 + 7;int T, n, m;int a[50];ll dp[42][maxn];void init() { scanf("%d %d", &n, &m); for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); memset(dp, 0, sizeof dp);}void solve() { dp[1][0] = dp[1][a[1]] = 1; for(int i = 1; i <= n; ++i) { for(int j = 0; j < maxn; ++j) { dp[i][j] += dp[i-1][j]; dp[i][j^a[i]] += dp[i-1][j]; } } ll ans = 0; for(int i = m; i < maxn; ++i) ans += dp[n][i]; printf("%lld\n", ans);}int main() { scanf("%d", &T); int kase = 1; while(T--) { init(); printf("Case #%d: ", kase++); solve(); } return 0;}
阅读全文
1 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- BZOJ1050 旅行comf [kruskal]
- bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级
- Spring MVC,403,404,500页面
- Spring入门概述(萌新必看)
- BZOJ1087 [SCOI2005]互不侵犯King 状态压缩DP
- HDU
- unix常用命令使用经验
- Arduino开发之Analog Sound Sensor
- springmvc常用注解标签详解
- 通过Ajax的方式上传文件
- linux下的用户管理详解
- sun.misc.BASE64Encoder找不到jar包的解决方法
- 《C和指针》读书笔记(四)
- Pycharm Unresolved reference导入编写py文件报错