UVALive 7721 K - 2-ME Set 集合dp,所有数的位或来表示状态。
2017-08-01 10:40
387 查看
/** 题目: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+10; const int M = 15; const int mod = 1e9+7; const int INF = 0x3f3f3f3f; int a , dp[32770], s , num ; struct node { int value, cnt; }t ; vector<node> v; int main() { int T, cas = 1, n; cin>>T; while(T--) { scanf("%d",&n); memset(num, 0, sizeof num); for(int i = 1; i <= n; i++){ scanf("%d",&a[i]); num[a[i]]++; } int m = n; int n = 0; for(int i = 1; i <= 20000; i++){ if(num[i]){ t .cnt = num[i]; t .value = i; n++; } } memset(dp, 0, sizeof dp); dp[0] = 1; //v.clear(); //v.push_back(node{0,1}); for(int i = 0; i < n; i++){ if(i==0) s[i] = t[i].value; else s[i] = s[i-1]|t[i].value; } for(int i = 0; i < n; i++){ for(int j = s[i]; j >= t[i].value; j--){ if((t[i].value&(j-t[i].value))==0) dp[j] = (dp[j]+(LL)dp[j-t[i].value]*t[i].cnt%mod)%mod; } } int ans = 0; for(int i = 1; i <= s[n-1]; i++) ans = (ans+dp[i])%mod; printf("Case #%d: %d\n",cas++,(ans-m+mod)%mod); } return 0; }
相关文章推荐
- UVA 11825 集合枚举 状态压缩 dp
- UVa 11795 - Mega Man's Mission (集合DP 状态压缩)
- 关于集合整数表示的一些技巧以及状态压缩dp入门(POJ3254)
- uvalive4794(集合+状态压缩)
- UVALive 6625 Diagrams & Tableaux (状态压缩DP)
- UVa 12563 Jin Ge Jin Qu hao(DP 多种状态表示)
- UVA 11825 dp、状态压缩、二进制法表示集合
- UVALive - 4260 Fortune Card Game (DP&状态转移)好题
- UVALive 6491 You win! 状态DP
- UVALive 3561 Low Cost Air Travel(多状态最短路,dp)
- 集合的二进制表示 && 状态压缩dp
- UVAlive 4999 状态压缩DP+最短路
- UVALive 2031 Dance Dance Revolution (舞步转移,状态压缩DP,4级)
- UVALive 2031 Dance Dance Revolution (舞步转移,状态压缩DP,4级)
- UVA - 1252 UVALive - 4643 状态压缩dp
- UVA11795——Mega Mans Missions(集合DP,状态压缩)
- uvalive 7834 状态压缩dp
- uvalive 4727 jump跳跃(dp/约瑟夫问题变形)
- UVALive 3363 String Compression (区间DP,4级)
- UVALive - 6952 Cent Savings (DP)