BZOJ2767:[JLOI2010]足彩投注

题目大意:

有n场比赛,告诉每场胜负平的概率,其他人押胜负平的概率

当所有比赛都押对时就中奖啦,所有押对的人平分奖金

有一种复式投注,可以让你某些题押几个结果(详见题目)

让得奖金的期望最大

具体思路:

发现押注数只有1e4,那么就可以dp啦

f[i][j][k]表示前i个,用了j个2,用了k个3的最大期望

暴力dp一下就好啦

AC代码

#include<bits/stdc++.h>
using namespace std;
int n,i,j,N,M,U,now[100010],k;
long double  p[10010][5],q[10010][5],a[10010][5],dp[10010][20][10];
bool cmp(long double  a,long double  b){return a>b;}
int main()
{
    scanf("%d%d%d%d",&n,&N,&M,&U);
    for(i=1;i<=n;i++)
    {
        cin>>p[i][0]>>p[i][1]>>p[i][2]>>q[i][0]>>q[i][1]>>q[i][2];
        for(j=0;j<=2;j++)a[i][j]=p[i][j]/q[i][j];
        sort(a[i],a[i]+3,cmp);
        now[i]=0;
    }
    dp[0][0][0]=1.0;
    for(i=1;i<=n;i++)
        for(j=0;j<=19;j++)
            for(k=0;k<=9;k++)
            if(pow(2,j)*pow(3,k)<=(long double)U+0.1)
            {
                dp[i][j][k]=dp[i-1][j][k]*a[i][0];
                if(j)dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-1][k]*(a[i][0]+a[i][1]));
                if(k)dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k-1]*(a[i][0]+a[i][1]+a[i][2]));
                dp[i][j][k]=dp[i][j][k];
            }
    long double  ans=0.0;
    for(j=0;j<=19;j++)
        for(k=0;k<=9;k++)
        ans=max(ans,dp[n][j][k]);
    printf("%.3Lf",log(ans/N*M));
    return 0;
}
原文地址:https://www.cnblogs.com/Orange-User/p/8466187.html