codeforces 167B Wizards and Huge Prize 概率dp

题意:给定n个对手,至少要击败其中 l 个人,现在有口袋容量为 k下面n个数字表示击败这个人的概率

下面n个数字(若为-1表示击败这个人可以获得一个金币,若>0则表示可以增加口袋容量为这个数字)

求:至少击败其中的l个人,且获得的总口袋容量 >= 获得的金币个数 的概率是多少。(即任何时候金币都不能放不下)

思路:设dp[i][j][k]表示当前前i个人已经战胜j个人,且剩余口袋容量为k的概率,简单的推下公式即可。有一点需要主要,可能一开始

剩余口袋容量<0后来大于0,所以要加一个常数不让它为负,只要最后剩余容量>=0即可。详见代码:

/*********************************************************
  file name: codeforces167B.cpp
  author : kereo
  create time:  2015年02月01日 星期日 21时34分15秒
*********************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int sigma_size=26;
const int N=200+50;
const int MAXN=100000+50;
const int inf=0x3fffffff;
const double eps=1e-8;
const int mod=100000000+7;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define PII pair<int, int>
#define mk(x,y) make_pair((x),(y))
int n,m,k;
int a[N];
double p[N],dp[N][N][2*N+10];
int main(){
    while(~scanf("%d%d%d",&n,&m,&k)){
        memset(dp,0,sizeof(dp));
        dp[0][0][N+k]=1.0;
        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]);
        for(int i=1;i<=n;i++){
            for(int j=0;j<i;j++){
                for(int k=0;k<=2*N;k++){
                    if(a[i] == -1){
                        if(k)
                            dp[i][j+1][k-1]+=dp[i-1][j][k]*p[i];
                    }
                    else
                        dp[i][j+1][min(2*N,k+a[i])]+=dp[i-1][j][k]*p[i];
                    dp[i][j][k]+=dp[i-1][j][k]*(1-p[i]);
                }
            }
        }
        double ans=0;
        for(int i=m;i<=n;i++)
            for(int j=N;j<=2*N;j++)
                ans+=dp[n][i][j];
        printf("%f\n",ans);

    }
	return 0;
}
时间: 2024-10-03 23:23:00

codeforces 167B Wizards and Huge Prize 概率dp的相关文章

Codeforces 167B Wizards and Huge Prize 概率dp(水

题目链接:点击打开链接 题意: 给定n个对手,至少要击败其中 l 个人,现在有口袋容量为 k 下面n个数字表示击败这个人的概率 下面n个数字(若为-1表示击败这个人可以获得一个金币,若>0则表示可以增加口袋容量为这个数字) 问: 至少击败其中的l个人,且获得的总口袋容量 >= 获得的金币个数 的概率是多少.(即任何时候金币都不能放不下) 思路: 概率dp 要注意的是有可能口袋容量是负数,但最后的时候变成了正数,所以要给口袋容量都+N, #include <iostream> #in

codeforces 235B Let&#39;s Play Osu! 概率dp

题意:给定n表示有n个格子,下面每个格子为O的概率是多少.对于一段连续 x 个O的价值就是 x^2 ;求获得的价值的期望是多少. 思路:n^2=n×(n-1)+n,设ai为第i段连续O的长度,∑ai^2 = ∑[ ai+ ai*(ai-1) ] = ∑ ai*(ai-1) + ∑ai = ∑ C(ai, 2)*2 + ∑ai,那么问题可以转 化为求长度大于1的连续段数*2+O的个数的总期望. ∑ai我们可以理解为O的总个数,所以它的期望为∑pi: C(ai, 2)*2我们可以认 为是连续ai个O

Codeforces 235B Let&#39;s Play Osu! (概率dp求期望+公式变形)

B. Let's Play Osu! time limit per test:2 seconds memory limit per test:256 megabytes You're playing a game called Osu! Here's a simplified version of it. There are n clicks in a game. For each click there are two outcomes: correct or bad. Let us deno

Codeforces 235B Let&#39;s Play Osu! 概率dp(水

题目链接:点击打开链接 给定n表示有n个格子 下面每个格子为O的概率是多少. 对于一段连续 x 个O的价值就是 x*x ; 问: 获得的价值的期望是多少. 思路: 把公式拆一下.. #include <cstdio> const int N = 100005; double dp[N][2], p[N]; int main(){ int n; scanf("%d", &n); for(int i = 1; i <= n; i ++) { scanf("

Codeforces Div.301D Bad Luck Island(概率dp+记忆化搜索)

一道概率dp问题. 题目链接:http://codeforces.com/contest/540/problem/D 题目大意:一个岛上有r个石头,s个剪子,p个布,他们之间随机挑出两个相遇,如果不是相同物种,就会有一个消失,分别求出最后这座岛上只剩下一个物种的概率. 我们用dp[i][j][k]来存储i个石头,j个剪刀,k个布时,某物种的存活概率,共dp三次,算出三个物种分别的概率. 首先,我们需要把对应想求的物种概率初始化,这里以石头为例,那么对于i从1到r,不难理解dp[i][0][0]=

Codeforces 148D Bag of mice:概率dp 记忆化搜索

题目链接:http://codeforces.com/problemset/problem/148/D 题意: 一个袋子中有w只白老鼠,b只黑老鼠. 公主和龙轮流从袋子里随机抓一只老鼠出来,不放回,公主先拿. 公主每次抓一只出来.龙每次在抓一只出来之后,会随机有一只老鼠跳出来(被龙吓的了...). 先抓到白老鼠的人赢.若两人最后都没有抓到白老鼠,则龙赢. 问你公主赢的概率. 题解: 表示状态: dp[i][j] = probability to win(当前公主先手,公主赢的概率) i:剩i只白

CodeForces 148D. Bag of mice(概率dp啊 )

题目链接:http://codeforces.com/problemset/problem/148/D D. Bag of mice time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output The dragon and the princess are arguing about what to do on the New Year'

Codeforces Round #105 (Div. 2) D 概率DP

题目 呃 琢磨了半天还是琢磨出来了,题意有些模糊哈,有w个白色物品,b个黑色物品,A,B轮着抽,A先开始,谁先抽到白色谁赢,若最终都没有抽到白色 则算B赢,抽出来的物品不会放回去,B抽完以后 物品还会有一个额外产生丢失,问A赢的概率为多少 依旧是以目标状态为边界,当前状态到目标状态所需要的概率为 方程 dp[i][j] 代表当前轮到A抽的时候,还有i个白色的j个黑色的A赢的概率为多少 则当前转移可能有四种 1:A抽到了白色的,那么直接赢了,接下来不需要继续,所以没有与其它状态方程有联系 2:A抽

Codeforces Round #301 (Div. 2) D 概率DP

一个岛上住着三种生物,石头(R).剪刀(S)和布(P).两个不同的生物见面会打架,并且有一方死亡,已知各生物碰见的概率是一样的,求最后岛上只留下剪刀.石头.布的概率. dp[r][s][p] : 石头,剪刀,布分别剩下r,s,p的概率这时,布和石头打一架,将转移到dp[r-1][s][p],而布和石头打架的概率是(p*r)/(r*s + s*p + p*r), 同理,dp[r][s][p]可以转移到状态dp[r][s-1][p] 和dp[r][s][p-1]; 最后统计结果就行. #includ