2014牡丹江——Domination
2016-02-04 08:43
288 查看
题目链接
题意:
给一个n*m的矩阵,每天随机的在未放棋子的格子上放一个棋子。求每行至少有一个棋子,每列至少有一个棋子的天数的期望
(1 <= N, M <= 50).
分析:
比較明显的概率DP,难点在于怎样设计状态。覆盖了多少行和列是不可缺少的,之后比較关键的就是想到还有一个属性:多少个交叉点(即放过的点)
题意:
给一个n*m的矩阵,每天随机的在未放棋子的格子上放一个棋子。求每行至少有一个棋子,每列至少有一个棋子的天数的期望
(1 <= N, M <= 50).
分析:
比較明显的概率DP,难点在于怎样设计状态。覆盖了多少行和列是不可缺少的,之后比較关键的就是想到还有一个属性:多少个交叉点(即放过的点)
double dp[55][55][2550]; bool vis[55][55][2550]; int tot; int n, m; inline double getp(int xx, int yy) { return (xx * 1.0) / yy; } double dpf(int x, int y, int z) { if (x > n || y > m || z > tot) return 0; if (x == n && y == m) return 0.0; if (vis[x][y][z]) return dp[x][y][z]; vis[x][y][z] = true; int a = x * y - z; int b = tot - (x * m + y * n - x * y); int xc = x * m - x * y; int yc = y * n - x * y; int sum = a + b + xc + yc; dp[x][y][z] = 0; if (a) dp[x][y][z] += getp(a, sum) * dpf(x, y, z + 1); if (b) dp[x][y][z] += getp(b, sum) * dpf(x + 1, y + 1, z + 1); if (xc) dp[x][y][z] += getp(xc, sum) * dpf(x, y + 1, z + 1); if (yc) dp[x][y][z] += getp(yc, sum) * dpf(x + 1, y, z + 1); dp[x][y][z] += 1.0; return dp[x][y][z]; } int main() { int T; RI(T); while (T--) { RII(n, m); tot = n * m; memset(vis, 0, sizeof(vis)); printf("%.12lf\n", dpf(0, 0, 0)); } return 0; }
相关文章推荐
- iOS开发之多线程技术——NSOperation篇
- 策略模式
- 第五话-依赖倒转原则
- linux Socket 编程
- 从零自学Hadoop(18):Hive的CLI和JDBC
- 【ASP.NET Identity系列教程(二)】运用ASP.NET Identity
- HDU 1050:Moving Tables
- NET 利用 jquery+ztree 实现 角色权限设置(以树结构显示导航菜单)
- Java实现冒泡排序算法
- Linux 容器技术史话:从 chroot 到未来
- Python简单登录密码比对
- 1号店的分布式搜索引擎的架构实践
- 【hdu2815-Mod Tree】高次同余方程-拓展BadyStepGaintStep
- .Net配置文件——反射+配置文件存储类型实例
- Java 中文 编码问题
- 2016SEM百度竞价如何分词【太原网络营销师】{郭文军}解析
- 【poj3243-Clever Y】高次同余方程-拓展BabyStepGiantStep
- LeetCode-55-Jump Game(贪心)-Medium
- centos vmware centos6.6 64位 kvm虚拟化安装配置 第四十二节课
- 工作半年总结