hihocoder #1075 : 开锁魔法III
来源:互联网 发布:适合英语六级听力软件 编辑:程序博客网 时间:2024/04/29 16:45
时间限制:6000ms
单点时限:1000ms
内存限制:256MB
- 样例输入
45 12 5 4 3 15 22 5 4 3 15 32 5 4 3 15 42 5 4 3 1
- 样例输出
0.0000000000.6000000000.9000000001.000000000
描述
一日,崔克茜来到小马镇表演魔法。
其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它。初始时,崔克茜将会随机地选择 k 个盒子用魔法将它们打开。崔克茜想知道最后所有盒子都被打开的概率,你能帮助她回答这个问题吗?
输入
第一行一个整数 T (T ≤ 100)表示数据组数。 对于每组数据,第一行有两个整数 n 和 k (1 ≤ n ≤ 300, 0 ≤ k ≤ n)。 第二行有 n 个整数 ai,表示第 i 个盒子中,装有可以打开第 ai 个盒子的钥匙。
输出
对于每组询问,输出一行表示对应的答案。要求相对误差不超过四位小数。
对于某个箱子集合,若打开其中任意一个箱子都能依次使用箱子中的钥匙打开其他所有箱子,暂且把这样的箱子集合称作环。
比如在测试案例1中,(1,2,5)是一个环,(3,4)也是一个环。显然,不论打开(1,2,5)中的哪个箱子,其它两个箱子也会被打开。
这题的要求是打开所有的箱子的概率。打开箱子的总方法数是C(n,k),所有本题的关键是求打开所有箱子的方法数。
除此之外还要统计有多少环,以及每个环中的元素个数。
动态规划:
dp[i][j]表示用j把钥匙打开前i个环箱子的方法数。
dp[0][0]=1
dp[i+1][j+l]+=dp[i][j]*C(count(i+1),l) count(i+1)表示第i+1个环中的箱子数量
即用j+l把钥匙打开i+1的方法数,即打开第i+1个环共用了l把钥匙。
在程序中count的计数是从0开始的,即count(i)实际表示的第i+1环中的箱子数量。
#include <iostream>#include <iomanip>#include <vector>#include <math.h>#include "string.h"using namespace std;int main(){int t;cin >> t;vector<vector<double>>c(301, vector<double>(301));for (int i = 0; i <= 300; i++){c[i][0] = c[i][i] = 1.0;for (int j = 1; j < i; j++)c[i][j] = c[i - 1][j - 1] + c[i-1][j];}while (t--){int n, k;cin >> n >> k;int *box;int *visit;box = new int[n + 1];visit = new int[n + 1];for (int i = 1; i <= n; i++){cin >> box[i];visit[i] = 0;}vector<int> count;for (int i = 1; i <= n; i++){int sum = 0;int tmp = i;while (visit[tmp] == 0){visit[tmp] = 1;tmp = box[tmp];sum++;}if (sum!=0)count.push_back(sum);}int ring_num = count.size();if (ring_num > k){cout << "0.000000000" << endl;continue;}vector<vector<double>>dp(301, vector<double>(301));dp[0][0] = 1.0;for (int i = 0; i < ring_num; i++){for (int j = 0; j < k; j++){if (fabs(dp[i][j]) > 0.000001){for (int l = 1; l <= count[i]&&j+l<=k; l++)dp[i + 1][j + l] += dp[i][j] * c[count[i]][l];}}}printf("%.9f\n", dp[ring_num][k] / c[n][k]);//cout << setprecision(9) << dp[ring_num][k] / c[n][k] << endl;}system("pause");return 0;}
真是哔了狗了,为什么输出不能用steprecision!!!!
0 0
- hihoCoder 1075 开锁魔法III
- hihocoder #1075 : 开锁魔法III
- hihocoder #1075 : 开锁魔法III
- hihocoder 1075 开锁魔法III(置换+DP)
- #1075 : 开锁魔法III
- hihoCoder 1075 开锁魔法III (dp,划分阶段)
- [dp+组合数学] hihocoder 1075 开锁魔法III
- [ACM] hihoCoder 1075 开锁魔法III (动态规划,组合数学)
- [DP 组合] BZOJ5004 & Hihocoder1075. 开锁魔法 III
- Hrbust 2250 开锁魔法III【Dp+long double】
- 开锁魔法 DP+组合数
- bzoj 5004: 开锁魔法II
- 哈理工2249开锁魔法 概率dp
- Hrbust 2249开锁魔法II(dp)
- hrbust 2249 开锁魔法II【概率dp】
- 5004: 开锁魔法II 概率DP
- 开锁
- 开锁
- PEM文件&X.690研究
- java知识小盘点(二)——线程同步问题
- 从尾到头打印链表
- Leetcode Reverse Bits
- leetcode Letter Combinations of a Phone Number
- hihocoder #1075 : 开锁魔法III
- HDU4267
- 讲的非常好的“==”与equals()方法的比较,尤其是对于字符串的例子,非常棒
- Android开发的笔记
- java异常---java.lang.IllegalStateException: No output folder
- poj 2153 Rank List
- java错误--- MyEclipse 启动报错:'Building workspace' has encountered a problem解决方法
- java学习---Eclipse 连接MySql数据库总结
- 《项目——网络音乐播放器》——网络请求之for循环内嵌套的try...catch...里面放break