hihoCoder 1075 开锁魔法III (dp,划分阶段)
来源:互联网 发布:国考面试报网络培训班 编辑:程序博客网 时间:2024/05/16 08:59
题意:
一日,崔克茜来到小马镇表演魔法。
其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它。初始时,崔克茜将会随机地选择 k 个盒子用魔法将它们打开。崔克茜想知道最后所有盒子都被打开的概率,你能帮助她回答这个问题吗?
题解:
我们发现对于打开盒子会形成环,当打开一个盒子时会得到某个盒子的钥匙,不断打开最后回到起始盒子,这样就可以将盒子分成多个部分,我们至少要选择每个部分中的一个盒子,那么根据盒子分列进行阶段的划分,dp[i][j]表示到第i部分用了j次操作能打开全部盒子的方案数。这是个排列组合的问题,刚才求解的方案数/C[n][k]就是要求的概率。dp方程:dp[i][j]=dp[i-1][j-k]*C[m][k] k表示第i次用了k个操作。m表示有分成了多少个部分。
#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<queue>#include<map>#include<set>using namespace std;#define B(x) (1<<(x))typedef long long ll;void cmax(int& a,int b){ if(b>a)a=b; }void cmin(int& a,int b){ if(b<a)a=b; }const int oo=0x3f3f3f3f;const int MOD=1000000007;const int maxn=305;double dp[maxn][maxn],C[maxn][maxn];int cnt[maxn],vis[maxn];int a[maxn];void Init(){ for(int i=0;i<maxn;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]; }}int main(){ int n,m,k,T,u; Init(); scanf("%d",&T); while(T--){ scanf("%d %d",&n,&k); memset(vis,0,sizeof vis); m=0; for(int i=1;i<=n;i++)scanf("%d",&a[i]),vis[i]=0; for(int i=1;i<=n;i++){ if(!vis[i]){ vis[i]=1; u=a[i]; m++; cnt[m]=1; while(u!=i&&!vis[u]){ vis[u]=1; cnt[m]++; u=a[u]; } } } if(k<m){ printf("%.9lf\n",0.0); continue; } for(int i=0;i<=m;i++) for(int j=0;j<=n;j++) dp[i][j]=0.0; dp[0][0]=1.0; for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ for(int l=1;l<=cnt[i];l++){ if(j-l>=0) dp[i][j]+=dp[i-1][j-l]*C[cnt[i]][l]; } } } double ans=dp[m][k]/C[n][k]; printf("%.9lf\n",ans); } return 0;}
0 0
- hihoCoder 1075 开锁魔法III (dp,划分阶段)
- hihocoder 1075 开锁魔法III(置换+DP)
- hihoCoder 1075 开锁魔法III
- hihocoder #1075 : 开锁魔法III
- hihocoder #1075 : 开锁魔法III
- [dp+组合数学] hihocoder 1075 开锁魔法III
- #1075 : 开锁魔法III
- [DP 组合] BZOJ5004 & Hihocoder1075. 开锁魔法 III
- [ACM] hihoCoder 1075 开锁魔法III (动态规划,组合数学)
- Hrbust 2250 开锁魔法III【Dp+long double】
- 开锁魔法 DP+组合数
- 哈理工2249开锁魔法 概率dp
- Hrbust 2249开锁魔法II(dp)
- hrbust 2249 开锁魔法II【概率dp】
- 5004: 开锁魔法II 概率DP
- bzoj 5004: 开锁魔法II
- hihocoder #1035 : 自驾旅行 III 树形DP
- hdu1028 Ignatius and the Princess III(DP整数划分)
- Linux中查看CPU信息
- ssh整合action中获取service为空解决方案
- BNU --- LiuLibo's Party
- 单链表的创建、销毁与K结点处插入新结点
- [python学习]异常
- hihoCoder 1075 开锁魔法III (dp,划分阶段)
- BT协议的详细分析
- 例题6-8 树 UVa548
- BCB中一些常用函数
- 【猫猫的Unity Shader之旅】之UV动画
- Python 环境搭建
- 最详细的JavaScript和事件解读
- printf非常奇怪的参数问题
- Eclipse+CDT+MinGW,搭建C++开发环境