HDU 5117 Fluorescent
2015-09-16 17:10
190 查看
题目描述:
DescriptionMatt, a famous adventurer who once defeated a pack of dire wolves alone, found a lost court. Matt finds that there are N fluorescent lights which seem to be the stars from the firmament. What’s more, there are M switches that control these fluorescent lights. Each switch is connected to a group of lights. When Matt touches a switch, all the lights connected to it will change their states (turning the dark on, turning the bright off).
Initially, all the fluorescent lights are dark. For each switch, Matt will touch it with probability 1 .
As a curious gentleman, Matt wants to calculate E[X3], where X represents the number of bright lights at the end, E[X3] represents the expectation of cube of X.
Input
The first line contains only one integer T , which indicates the number of test cases.
For each test case, the first line contains N, M (1 ≤ N, M ≤ 50), denoting the number of fluorescent lights (numbered from 1 to N ) and the number of switches (numbered from 1 to M ).
M lines follow. The i-th line begins with an integer Ki (1 ≤ K i ≤ N ). K i distinct integers l ij(1 ≤ l ij ≤ N ) follow, denoting the fluorescent lights that the i-th switch controls.
题解:
如果是求期望,那么因为期望的可加性,我们看每一个灯对答案的贡献,xi是0或者是1,有pi的概率,然后虽然是相关的,但是累加起来就好了.但是要求x^3的期望.我们把表达式写出来:先是EX的表达式:EX*2^m = (所有情况遍历)(x1+…+xn).因为期望的可加性,EX=(遍历n)(1*pi). 显然E(X^3)不能EX直接三次方.因为E(x^3)的含义是在某种情况下,把signma(x1+…+xn)搞一个三次方,之后的期望.因此我们把(signma(x1+…+xn))^3拆开.之后就有加法啦.然后利用期望的线性可加性就好算了.对于比如x1*x2*x3这种,显然都是1才有意义,那么我们需要计算都是1一共有多少种情况数.可以用dp[s]表示当前三个灯的状态,这样不用关注另外的灯的状态了.其实有一个小技巧,直接枚举三次1~n,不管ijk是谁,直接来一次就好了.具体看代码.重点:
(1)期望的线性可加性:先利用指示器的思路把每一个变量的贡献写出来,然后写出期望的表达式,不好写就写出所有情况的和的形式.然后研究拆开成几个部分的加法,之后单独考虑加法就行了.代码:
#include <cstdio> #include <cstring> #include <string> #include <algorithm> using namespace std; typedef long long ll; const ll mod = 1e9 + 7; ll g[51],f[51][8],ans; int n,m; void solve() { scanf("%d%d",&n,&m); //printf("%d %d\n",n,m); memset(g,0,sizeof g); ans = 0; for (int i = 1;i <= m;i++) { int num; scanf("%d",&num); for (int j = 1;j <= num;j++) { int x; scanf("%d",&x); g[i] |= (1ll << x); } } for (int i = 1;i <= n;i++) for (int j = 1;j <= n;j++) for (int k = 1;k <= n;k++) { memset(f,0,sizeof f); f[0][0] = 1; for (int no = 1;no <= m;no++) for (int st = 0;st < (1<<3);st ++) { f[no][st] = (f[no][st] + f[no-1][st]) % mod; int mask = 0; if (g[no] & (1ll<<i)) mask |= 1; if (g[no] & (1ll<<j)) mask |= 2; if (g[no] & (1ll<<k)) mask |= 4; //printf("%d %I64d\n",no,mask); for (int stp = 0;stp < (1<<3);stp ++) if ((stp ^ mask) == st) { f[no][st] = (f[no][st] + f[no-1][stp]) % mod; } } //printf("%I64d\n",f[m][8]); ans = (ans + f[m][7]) % mod; } static int ca = 0; printf("Case #%d: %I64d\n",++ca,ans); } int main() { // freopen("in.txt","r",stdin); int t; scanf("%d",&t); while (t--) solve(); }
相关文章推荐
- CPM、CPC、CPA、PFP、CPS、CPL、CPR都是什么意思?
- Objective-C 【时间与日期处理】
- npoi读写excel导致excel文件格式损坏
- java 指定时间时间戳
- 用NPOI操作EXCEL--画线(HSSFClientAnchor和HSSFSimpleShape 使用)
- 卓有成效的管理者
- [转]深入hibernate的三种状态
- liferay中如何获取实例的id和portletId
- 服务器控件中使用<%#...>, JS和html控件中使用<%=...>
- tftp通过“USB转串”连接主机和开发板
- Hadoop-2.4.1安装配置
- 关于“特权解除、陷入模拟”的理解
- JSP四大作用域
- JAVA中获取当前系统时间
- 时间戳转时间
- Android中判断网络是否可用
- C++的重载(overload)与重写(override
- css通配符
- jQuery时间冒泡
- 海信电视 LED55K370 升级固件总结【含固件下载地址】