• codeforces---167BWizards and Huge Prize 概率DP


    题目链接:https://codeforces.com/problemset/problem/167/B

    题目大意:有n场比赛,你至少要赢l次才算优秀,你有一个大小为k的包,每场比赛的胜率为$p_i$,每场比赛赢得的奖品为$a_i$如果$a_i<0$则是奖品,否则就是一个容量为$a[i]$的背包。问你在优秀的时候拿走所以赢得奖品的概率。

    Examples

    Input
    3 1 0
    10 20 30
    -1 -1 2
    Output
    0.300000000000
    Input
    1 1 1
    100
    123
    Output
    1.000000000000

    DP。。。真的有点无力。。。。

    设置状态为$dp[i][j][k]$,表示为前$i$场比赛赢得$j$场后的背包剩余空间$k$。由于比赛的顺序是无序的,那么我们可以对初始状态背包容量+200(因为最多200个奖品),那么这样就可以随便拿了,最后确定状态的时候小于200的就直接舍弃了。

    以下是AC代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int mac=210;
    
    int a[mac];
    double p[mac];
    double dp[mac][mac][2*mac];
    
    int main()
    {
        int n,l,v;
        scanf ("%d%d%d",&n,&l,&v);
        for (int i=1; i<=n; i++)
            scanf ("%lf",&p[i]),p[i]/=100;
        for (int i=1; i<=n; i++)
            scanf ("%d",&a[i]);
        dp[0][0][v+200]=1;
        for (int i=0; i<n; i++)
            for (int j=0; j<=i; j++)
                for (int k=0; k<=400; k++){//枚举空间
                    int last=min(k+a[i+1],400);
                    dp[i+1][j][k]+=dp[i][j][k]*(1-p[i+1]);//本场失败
                    if (last>0)
                        dp[i+1][j+1][last]+=dp[i][j][k]*p[i+1];
                }
        double ans=0;
        for (int i=200; i<=400; i++)
            for (int j=l; j<=n; j++)
                ans+=dp[n][j][i];
        printf("%.10f
    ",ans);
        return 0;
    }
    路漫漫兮
  • 相关阅读:
    排序算法(一)冒泡法
    java是传值还是传引用
    赫夫曼树与赫夫曼编码
    数据结构的相关概念
    字符集和字符编码的区别
    redis为什么选择单线程工作模型
    GET和POST请求的核心区别
    MySQL数据类型及后面小括号的意义
    java中的数据类型
    Jedis无法连接centOS7上的redis
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13234976.html
Copyright © 2020-2023  润新知