zoukankan      html  css  js  c++  java
  • Codeforces Round #363 LRU(概率 状压DP)

    状压DP:

    先不考虑数量k, dp[i]表示状态为i的概率,状态转移方程为dp[i | (1 << j)] += dp[i],最后考虑k, 状态表示中1的数量为k的表示可行解。

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<vector>
    #include<cmath>
    #include<utility>
    using namespace std;
    typedef long long LL;
    const int N = 1008, INF = 0x3F3F3F3F;
    #define MS(a, num) memset(a, num, sizeof(a))
    #define PB(A) push_back(A)
    #define FOR(i, n) for(int i = 0; i < n; i++)
    double dp[1 << 21];
    double ans[30];
    double p[30];
    int main(){
        int n, k;
        cin>>n>>k;
        int cnt = 0;
        for(int i= 0; i < n; i++){
            scanf("%lf", &p[i]);
            if(p[i] < 1e-6){
                cnt++;
            }
        }
        k = min(k, n - cnt);
        if(n <= k){
            printf("1.0");
            for(int i = 1; i < n; i++){
                printf(" 1.0");
            }
            printf("
    ");
        }else{
            dp[0] = 1;
            for(int i = 0; i < (1 << n); i++){
                double sum = 0;
                for(int j = 0; j < n; j++){
                    if((i & (1 << j) ) == 0){
                        sum += p[j];
                    }
                }
                //cout<<sum<<"#
    ";
                for(int j = 0 ; j < n; j++){
                    if( (i & (1 << j) ) == 0){
                        dp[i | (1 << j)] += dp[i] * p[j] / sum;
                    }
                }
            }
            for(int i = 0; i < (1 << n); i++){
                int cnt = 0;
                int tp = i;
                while(tp){
                    cnt++;
                    tp = tp & (tp - 1);
                }
                if(cnt == k){
                    for(int j = 0; j < n; j++){
                        if(i & (1 << j)){
                            ans[j] += dp[i];
                        }
                    }
                }
    
            }
    
            printf("%.8f", ans[0]);
            for(int i = 1; i < n; i++){
                printf(" %.8f", ans[i]);
            }
            printf("
    ");
    
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    1月27日 常用函数
    1月25日 JavaScript的DOM操作
    1月25日 JavaScript简介与语法
    1月24日 样式表案例
    5月14日 数字顺序打印并求和
    5月14日 根据班级人数,求平局分,最大值,最小值
    5月14日 九九乘法口诀
    5月14日 打印100以内与7有关的数
    5月14日 函数练习 100以内奇数的和
    5月14日 枚举类型
  • 原文地址:https://www.cnblogs.com/IMGavin/p/5740656.html
Copyright © 2011-2022 走看看