题目大意:
有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; }