zoukankan      html  css  js  c++  java
  • [hihocoder 1075] 开锁魔法III

    题意:小朋友有N个盒子,每个盒子装着打开第ai个盒子的钥匙,小朋友一开始可以使用洪荒之力打开k个盒子,求他能开完所有盒子的概率

    题解:

    DP+组合数

    首先几个盒子通过多次打开一定会形成一个环,设每个环的盒子数为cnt[i]

    状态:dp[i][j]表示前i个盒子用j个钥匙打开的方案数

    转移:dp[i+1][j+k]=∑dp[i][j]*C[cnt[i]][k]

    ps:dp数组和C数组要开double,double的上界大约可以到1*10^308(汗)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    using namespace std;
    
    const int N = 310;
    
    int T,n,m,cnt[N],a[N];
    double dp[N][N],c[N][N];
    bool vis[N];
    
    int gi() {
      int x=0,o=1; char ch=getchar();
      while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
      if(ch=='-') o=-1,ch=getchar();
      while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
      return o*x;
    }
    
    void pre() {
      c[0][0]=1.0;
      for(int i=1; i<=300; i++) {
        c[i][0]=c[i][i]=1;
        for(int j=1; j<i; j++)
          c[i][j]=c[i-1][j]+c[i-1][j-1];
      }
    }
    
    int main() {
      pre();
      int T=gi();
      while(T--) {
        memset(cnt,0,sizeof(cnt));
        memset(dp,0,sizeof(dp));
        memset(vis,0,sizeof(vis));
        int n=gi(),m=gi(),tmp;
        for(int i=1; i<=n; i++) a[i]=gi();
        for(int i=1; i<=n; i++) {
          if(vis[i]) continue;
          vis[i]=1,tmp=a[i],cnt[++cnt[0]]=1;
          while(!vis[tmp]) cnt[cnt[0]]++,vis[tmp]=1,tmp=a[tmp];
        }
        dp[0][0]=1.0;
        for(int i=1; i<=cnt[0]; i++)
          for(int j=0; j<=m; j++)
    	for(int k=1; j+k<=m && k<=cnt[i]; k++) 
    	  dp[i][j+k]+=dp[i-1][j]*c[cnt[i]][k];
        printf("%.4f
    ", dp[cnt[0]][m]/c[n][m]);
      }
      return 0;
    }
    
  • 相关阅读:
    用循环链表求解约瑟夫问题
    Nim游戏变种——取纽扣游戏
    POJ-2726-Holiday Hotel
    常用排序算法总结(二)
    常用排序算法总结(一)
    找出数组中出现次数最多的那个数——主元素问题
    C99新特性:变长数组(VLA)
    linux tftp配置 (Ubuntu18.04)
    Ubuntu 18.04安装Samba服务器及配置
    记录学习Linux遇到的问题
  • 原文地址:https://www.cnblogs.com/HLXZZ/p/7528256.html
Copyright © 2011-2022 走看看