UVALive 7721 K - 2-ME Set 集合dp,所有数的位或来表示状态。
/**
题目:UVALive 7721 K - 2-ME Set
链接:https://vjudge.net/problem/UVALive-7721
题意:给定n个数,从中取出一个集合,至少包含两个元素,如果集合内任意两个元素取位与都是0,那么是合法集合。
如果5个数为{5,2,2,1,4}那么有9种。(5, 2), (5, 2), (2, 1), (2, 1, 4), (2, 4), (2, 1), (2, 1, 4), (2, 4), and (1, 4).
问最多有多少种合法集合。
思路:定义dp[i]表示构成集合i的方法数。注意这里的i不是状态压缩那种i,就是纯粹集合内所有的数都满足任意取位与为0,所有数位或起来的。
因为每个数大小最多为20000,从1到20000取位或发现最大为32767。所以dp数组大小为32770. dp[i] += dp[j];(j<i,(j&(i-j))==0) 逆序枚举j。 为了优化时间,相同的数自身和自身不可能在同一个集合,所以统一处理。
然后最终计算结果减去所有的单位集合,即每一个数作为一个集合的情况。 */ #include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
using namespace std;
typedef pair<int,int> P;
typedef long long LL;
const int N = 2e4+;
const int M = ;
const int mod = 1e9+;
const int INF = 0x3f3f3f3f;
int a[N], dp[], s[N], num[N];
struct node
{
int value, cnt;
}t[N];
vector<node> v;
int main()
{
int T, cas = , n;
cin>>T;
while(T--)
{
scanf("%d",&n);
memset(num, , sizeof num);
for(int i = ; i <= n; i++){
scanf("%d",&a[i]);
num[a[i]]++;
}
int m = n;
int n = ;
for(int i = ; i <= ; i++){
if(num[i]){
t[n].cnt = num[i];
t[n].value = i;
n++;
}
}
memset(dp, , sizeof dp);
dp[] = ;
//v.clear();
//v.push_back(node{0,1});
for(int i = ; i < n; i++){
if(i==) s[i] = t[i].value;
else s[i] = s[i-]|t[i].value;
}
for(int i = ; i < n; i++){
for(int j = s[i]; j >= t[i].value; j--){
if((t[i].value&(j-t[i].value))==)
dp[j] = (dp[j]+(LL)dp[j-t[i].value]*t[i].cnt%mod)%mod;
}
}
int ans = ;
for(int i = ; i <= s[n-]; i++) ans = (ans+dp[i])%mod;
printf("Case #%d: %d\n",cas++,(ans-m+mod)%mod);
}
return ;
}
UVALive 7721 K - 2-ME Set 集合dp,所有数的位或来表示状态。的更多相关文章
- bzoj2064: 分裂(集合DP)
......咸鱼了将近一个月,因为沉迷ingress作业越来越多一直没时间搞OI呜呜呜 题目大意:有一个初始集合(n个元素)和一个目标集合(m个元素)(1<=n,m<=10),两个操作 ...
- [UVALive 6661 Equal Sum Sets] (dfs 或 dp)
题意: 求从不超过 N 的正整数其中选取 K 个不同的数字,组成和为 S 的方法数. 1 <= N <= 20 1 <= K<= 10 1 <= S <= 15 ...
- 最大 k 乘积问题 ( 经典区间DP )
题意 : 设 NUM 是一个 n 位十进制整数.如果将 NUM 划分为 k 段,则可得到 k 个整数.这 k 个整数的乘积称为 NUM 的一个 k 乘积.试设计一个算法,对于给定的 NUM 和 k,求 ...
- UVALive - 6257 K - Chemist's vows 【DFS】【BFS】【DP】
题目链接 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- uvalive 6669 hidden tree(好壮压dp)
题目见option=com_onlinejudge&Itemid=8&page=show_problem&problem=4681">here 题意:给一个序列 ...
- K - Painful Bases 状压dp
Painful Bases LightOJ - 1021 这个题目一开始看,感觉有点像数位dp,但是因为是最多有16进制,因为限制了每一个数字都不同最多就有16个数. 所以可以用状压dp,看网上题解是 ...
- Codeforces Gym 100610 Problem K. Kitchen Robot 状压DP
Problem K. Kitchen Robot Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10061 ...
- UVa 11825 集合dp
#include <cstdio> #include <cstring> #include <iostream> #include <cmath> #i ...
- AGC 005D.~K Perm Counting(容斥 DP 二分图)
题目链接 \(Description\) 给定\(n,k\),求 满足对于所有\(i\),\(|a_i-i|\neq k\)的排列的个数. \(2\leq n\leq 2000,\quad 1\leq ...
随机推荐
- HDU1505(HDU1506的加强版)
昨天打 CF又跪了.近期睡不好睡不好睡不好-感觉整个人都累傻了,根本无办法写下去,只写了一题签到题就跪了orz..从未试过这么悲剧. 今天早上凭着我的意念("怨念").七点又起来了 ...
- R简易安装
post={"title":"my Blog post","content":"Here's my blog post" ...
- (转)Linux下内存映射文件的用法简介
简介: 内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,只是内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而非系统的页文件,而且在对 ...
- 转: 关于android 机型适配的问题
转: http://www.csdn.net/article/2015-09-08/2825645
- java将SSL证书导入系统密钥库
之前安装JIRA和Confluence,配置了SSL证书之后遇到应用程序链接的问题: SSL证书不被信任,导致JIRA和Confluence无法关联. 尝试过很多办法无果之后打算放弃. 最终还是放弃了 ...
- 基于c++11新标准开发一个支持多线程高并发的网络库
背景 新的c++11标准出后,c++语法得到了非常多的扩展,比起以往不论什么时候都要灵活和高效,提高了程序编码的效率,为软件开发者节省了不少的时间. 之前我也写过基于ACE的网络server框架,但A ...
- Git和Repo管理使用
Git和Repo管理使用简要介绍 http://blog.csdn.net/stevenhu_223/article/details/8828130 多仓库代码管理器Repo的安装,使用以及服务器搭建 ...
- 安卓Camera APP
一.Camera package android.hardware 该类用于设定图像捕获设置,开启/关闭预览,抓拍图片以及获取帧用于编码视频.这个类是Camera服务的客户端,用 ...
- [物理题+枚举] hdu 4445 Crazy Tank
题意: 给你N个炮弹的发射速度,以及炮台高度H和L1,R1,L2,R2. 问任选发射角度.最多能有几个炮弹在不打入L2~R2的情况下打入L1~R1 注意:区间有可能重叠. 思路: 物理题,发现单纯的依 ...
- Drupal显示白屏或500?
Drupal有时会显示白屏,或者500内部错误,这多半是由于PHP脚本什么地方有问题造成的.这个时候,可以先看看php.log里面有没有提示: [10-Oct-2013 15:55:26 Asia/S ...