zoukankan      html  css  js  c++  java
  • Q

    题目大意:

    一共有61个位置,标记为0~60。其中有10个重要位置,分别为:5, 12, 22, 29, 33, 38, 42, 46, 50 and 55。

    有一个筛子,一共6个面,标有1~6。摇到几走几步,开始的位置是在0,一共可以要10次。

    输入筛子摇出每个面的概率,输出经过这10个重要位置的概率。

    题解:

    概率DP问题,定义dp[i][j]为第i次摇筛子,处在位置j处。状态转移方程dp[i][j]=dp[i][j]+dp[i][j-k]*arr[k](1<=k<=6)。

    位置j处的答案为每一次在位置j处的概率和。

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N = 100;
    double dp[N][N];
    double arr[N];
    int mp[N] = { 0, 5, 12, 22, 29, 33, 38, 42, 46, 50 ,55 };
    void solve(int time){
        memset(dp, 0, sizeof dp);
        for (int i = 1; i <= 6; i++) cin >> arr[i];
        dp[0][0] = 1;
        for (int i = 1; i <= 10; i++)
            for (int j = 0; j <= 60; j++) {
                if (j >= 6) dp[i][j] += dp[i - 1][j - 6] * arr[6];
                if (j >= 5) dp[i][j] += dp[i - 1][j - 5] * arr[5];
                if (j >= 4) dp[i][j] += dp[i - 1][j - 4] * arr[4];
                if (j >= 3) dp[i][j] += dp[i - 1][j - 3] * arr[3];
                if (j >= 2) dp[i][j] += dp[i - 1][j - 2] * arr[2];
                if (j >= 1) dp[i][j] += dp[i - 1][j - 1] * arr[1];
    
            }
        for (int i = 1; i <= 10; i++) {
            double ans = 0;
            for (int j = 1; j <= 10; j++) {
                ans += dp[j][mp[i]];
            }
            printf("%d: %.1lf%%
    ", mp[i], ans*100);
        }
        if(time!=0) puts("");
    }
    int main()
    {
        int t;
        cin >> t;
        while (t--) solve(t); 
        return 0;
    }

    总结:概率dp与一般dp的区别。概率dp状态转移非乘即加,而一般的dp都是最大或者最小。还有一般的dp[i][j]表示的是前i个.....而概率dp[i][j]一般都是第i个..

  • 相关阅读:
    hdu4846 最大子正方形(dp)
    hdu4847 水题
    hdu4847 水题
    hdu4848 DFS 暴搜+ 强剪枝
    hdu4848 DFS 暴搜+ 强剪枝
    洛谷 P4999 烦人的数学作业(数位DP)
    洛谷 P4317 花神的数论题(数位DP || 快速幂)
    洛谷 P2657 [SCOI2009]windy数(数位DP)
    洛谷 P2602 [ZJOI2010]数字计数(数位DP)
    HDU 2089 不要62(数位DP)
  • 原文地址:https://www.cnblogs.com/Accepting/p/12574475.html
Copyright © 2011-2022 走看看