upc-Final Standings(dp)

38 篇文章 0 订阅
35 篇文章 1 订阅
题目描述

The GCPC 2019 is finally over. You have worked for five hours and have solved as many problems as possible. However, you still do not know which place you have got, since the scoreboard is still frozen. Of course you think that you and your team have won GCPC 2019.

As there is always a lengthy pause between the end of the contest and unfreezing the scoreboards (someone has to print the certificates and someone has to re-compile the solution slides), you want to use your time to determine how probable it is that your team has won GCPC 2019.

You know the final scoreboard, that is, for all teams which problems they have solved prior to the freeze and which problems they have attempted during the freeze. Also you know from last year how good each team is and you trust your own estimates of each problem’s difficulty. To be precise, if a team with strength s ∈ [0, 1] has attempted to solve a problem with difficulty d ∈ [0, 1], you assume that the probability of solving the problem is s · d.

As your team was very quick in solving the simple problems this year, you assume that a team can only have a higher place than you, if they have solved more problems (you assume that you will always win the tie-break).

输入

The first line of input contains two integers t and p (1 ≤ t, p ≤ 100), the number of teams and the number of problems in the contest. The teams are numbered 1 to t and the problems are numbered 1 to p. Your team is team t.

• The second line contains t − 1 real numbers s 1 ,…, st−1 (0 ≤ si ≤ 1 for each i), where si is the strength of team i.

• The third line contains p real numbers d1 ,… , dp (0 ≤ dj ≤ 1 for each j), where dj is the difficulty of problem j.

• Then follow t − 1 lines describing the state of the problems for the other teams. Every such line contains p characters c1 ,… , cp , where c j in the ith line describes the state of problem j for team i and is X if the team has solved the problem before the freeze, ? if the team submitted a program for this problem after the freeze, and - otherwise.

• The last line of input describes the problems your team solved with p characters, each being either X or -.

All real numbers in the input have at most six decimals.

输出

Output a single real number, the probability that your team won GCPC 2019. Your answer should have an absolute or relative error of at most 10−6.

样例输入
3 3
0.95 0.95
0.95 0.95 0.95
? ? ?
X X -
X X -
样例输出
0.264908
题意

t 组队伍, p 道题目,自己是第 t 只队伍;
接着给出前 t - 1 只队伍的能力值,再给出 p 道题目的难度值;
( 每只队伍做出这道题的概率 = 这只队伍的能力值 * 这道题的难度;)
接下来给出每只队伍的每道题目的做题情况
" X " 代表明确知道做出来了, “ - ” 代表明确知道没做出来, “ ? ” 表示不知道做没做出来;
(最后一行,也就是自己的队伍不会出现 " ? " );
问自己队伍最后获胜的概率是多大;
(自己队伍永远是做的最快的,也就是全场自己队伍出题数应该是最高的或者最高的之一,自己队伍就可获胜)

代码
#include<iostream>
#include<string>
#include<map>
#include<set>
//#include<unordered_map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<iomanip> 
#include<cmath>
#include<fstream>
#define X first
#define Y second
#define INF 0x3f3f3f3f
//#define pdi pair<double,int>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
const int mod=1e9+7;
const int maxn=910;
using namespace std;
double dp[110][110],s[110],d[110],ans=1;
char mp[110][110];
int main( )
{
    int t,p,sum=0;
    scanf("%d%d",&t,&p);
    for(int i=1;i<t;i++) scanf("%lf",&s[i]);
    for(int i=1;i<=p;i++) scanf("%lf",&d[i]);
    for(int i=1;i<=t;i++)
    {
        for(int j=1;j<=p;j++)
        {
            cin>>mp[i][j];
        }
    }
    for(int i=1;i<=p;i++) if(mp[t][i]=='X') sum++;
    for(int k=1;k<t;k++)
    {
        for(int i=0;i<=p;i++)
        {
            for(int j=0;j<=sum;j++)
            {
                dp[i][j]=0;
            }
        }
        dp[0][0]=1;
        for(int i=0;i<=p;i++)
        {
            for(int j=0;j<=sum;j++)
            {                   //dp [ i ] [ j ] : 前 i 道题目做出 j 道题的概率
                if(mp[k][i+1]=='X') dp[i+1][j+1]+=dp[i][j];//明确知道做出来了
                else if(mp[k][i+1]=='-') dp[i+1][j]+=dp[i][j];//明确知道没做出来
                else
                {
                    dp[i+1][j+1]+=dp[i][j]*(s[k]*d[i+1]);//如果做出来
                    dp[i+1][j]+=dp[i][j]*(1-s[k]*d[i+1]);//如果没做出来
                }
            }
        }
        double tmp=0;
        for(int i=0;i<=sum;i++) tmp+=dp[p][i];
        ans*=tmp;
    }
    printf("%.6f",ans);
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值