题目<2016/11/30>
2016-11-30 21:17
141 查看
1.HDU5731
轮廓线状压DP+裸的容斥原理。
首先考虑没有任何限制的多米诺骨牌的问题。
那么我们暴力DP的话就是让不放的为0,放了的为1.
但是太暴力了,我们可以这样想。
对于第i个位置,我们实际上只关心第i个位置的:
如果我们知道这个轮廓线的所有状态,我们通过枚举这个格子怎么放也可以达到效果。
步骤如下:
1.枚举轮廓线状态以及在轮廓线的最后一个格子的状态。
2.更新下一个格子的轮廓线的状态,容易注意到,我们的轮廓线只是平移了一个单位。
3.所以我们用位运算表示轮廓线的位置,非常好做。
注意向上的答案,需要用到m+1个元素。
就没别的好说的了。
预处理这个多米诺之后,我们通过容斥原理是很容易算出答案的。
有两个形式的容斥原理:
1.枚举至少满足每个状态,如果这个状态有偶数个1那么就减,否则就加。
2.枚举第一个违反条件的地方i,这个答案可以通过任意选减去第一次违反条件在j(j
SRM664.DIV1T2
题意是:
给你棵树,以1为根。现在要炸这个树。
点i没炸掉的几率是1/i。
现在问所有联通块的大小的平方的期望值。
感觉很神,首先我们用奇怪的方法把平方去掉。
转成树上有序点对数目。
用dp[x]表示点x能到达子树(含自己)的期望点的个数。
那么dp[x]=∑v∈son[x]dp[v]∗pr[x]
这个方程的意义在于,v能到达的点在x没炸的时候一定能到达。
怎么算答案呢?
我们用类似于点分治的想法(并不),考虑过子树根的点对(路径)对答案的贡献,以及根本身对答案的贡献,可知一共分三种情况。
1.根本身:pr[x]
2.根到子树里面:pr[x]∗dp[v]
3.过根的路径:dp[v]∗(dp[x]−dp[v]∗pr[x])
轮廓线状压DP+裸的容斥原理。
首先考虑没有任何限制的多米诺骨牌的问题。
那么我们暴力DP的话就是让不放的为0,放了的为1.
但是太暴力了,我们可以这样想。
对于第i个位置,我们实际上只关心第i个位置的:
如果我们知道这个轮廓线的所有状态,我们通过枚举这个格子怎么放也可以达到效果。
步骤如下:
1.枚举轮廓线状态以及在轮廓线的最后一个格子的状态。
2.更新下一个格子的轮廓线的状态,容易注意到,我们的轮廓线只是平移了一个单位。
3.所以我们用位运算表示轮廓线的位置,非常好做。
int f[2][1 << 17]; void Add(int s,int y) { int &x = f[cur][s & ((1 << m) - 1)]; if(s & (1 << m))x += y; if(x >= Mod)x -= Mod; } int solve() { cur = 0; if(n < m)swap(n,m); int S = (1 << m) - 1; f[0][S] = 1; for(int i = 0;i < n;++ i) { for(int j = 0;j < m;++ j) { cur ^= 1; memset(f[cur],0,sizeof(f[cur])); for(int s = 0;s <= S;++ s) { Add((s << 1),f[cur ^ 1][s]); if(j && !(s & 1))Add( ((s << 1) | 3),f[cur ^ 1][s]); if(i && !(s & (1 << (m - 1))))Add((s << 1) | 1 | (1 << m),f[cur ^ 1][s]); } } } return f[cur][S]; }
注意向上的答案,需要用到m+1个元素。
就没别的好说的了。
预处理这个多米诺之后,我们通过容斥原理是很容易算出答案的。
有两个形式的容斥原理:
1.枚举至少满足每个状态,如果这个状态有偶数个1那么就减,否则就加。
2.枚举第一个违反条件的地方i,这个答案可以通过任意选减去第一次违反条件在j(j
void cal() { while(~scanf("%d%d",&n,&m)) { m --; int S = 1 << m,ans = 0; for(int s = 0;s < S;++ s) //枚举列的分割 { int cur = 0,cnt = 0; for(int i = 0;i < m;++ i) { if(s & (1 << i))a[++ cnt] = 1 + cur,cur = 0; else ++ cur; } a[++ cnt] = cur + 1; for(int i = 1;i <= n;++ i)//枚举强制在第i行 { for(int j = 0;j < i;++ j) { int re = 1; for(int k = 1;k <= cnt;++ k) re = 1ll * re * f[a[k]][i - j] % Mod; if(!j)dp[i] = re; else dp[i] = (dp[i] - 1ll * re * dp[j] % Mod + Mod) % Mod; } } if(cnt & 1)ans = (ans + dp ) % Mod; else ans = (ans + Mod - dp ) % Mod; } printf("%d\n",ans); } }
SRM664.DIV1T2
题意是:
给你棵树,以1为根。现在要炸这个树。
点i没炸掉的几率是1/i。
现在问所有联通块的大小的平方的期望值。
感觉很神,首先我们用奇怪的方法把平方去掉。
转成树上有序点对数目。
用dp[x]表示点x能到达子树(含自己)的期望点的个数。
那么dp[x]=∑v∈son[x]dp[v]∗pr[x]
这个方程的意义在于,v能到达的点在x没炸的时候一定能到达。
怎么算答案呢?
我们用类似于点分治的想法(并不),考虑过子树根的点对(路径)对答案的贡献,以及根本身对答案的贡献,可知一共分三种情况。
1.根本身:pr[x]
2.根到子树里面:pr[x]∗dp[v]
3.过根的路径:dp[v]∗(dp[x]−dp[v]∗pr[x])
相关文章推荐
- [置顶] Android面试题目大全<完结部分>,Android笔试题目集锦
- 上机题目<构造表达式>
- <C/C++练习>九度OJ题目1101--1150解题练习(四)
- <剑指offer>之链表题目
- Crossed Ladders<poj2507题目一样>
- <杭电HDU> OJ题目分类
- 挑战程序设计竞赛里面的部分题目<用java写的>
- <C/C++算法>九度OJ题目1516--1557解题练习(十)
- <九度 OJ>题目1112:拦截导弹
- <九度 OJ>题目1012:畅通project
- android面试题目大全<完结部分>,android笔试题目集锦
- Android面试题目中容易遗漏的知识点<持续更新>
- <C/C++基础>九度OJ题目1359--1414解题练习(七)
- 图论和搜索题目推荐<汇总>
- PHP面试出场率较高的题目<转载>
- 漫谈<<离散数学及其应用>> 第二章的计算机题目解答。
- 【JAVA】在网上看到的一些题目,在此做一些整理<此贴不定期更新>
- hdu1815 2sat + 二分 + 建图<不错的题目>
- 网易2009年校园招聘--一道关于<list>的STL题目
- 三分法(Ternary Search)求解凸(凹)函数的极值问题<题目篇>