NC20125. [JLOI2010]足彩投注
描述
了解足球彩票的人可能知道,足球彩票中有一种游戏叫做“胜负彩”,意为猜比赛的胜负。下面是一些与胜负彩有关的术语:
注 :每一组有效组合数据。
投 注:彩民以现金购买足球彩票的行为。
单式投注:彩民对于所有球队的比赛成绩均只选择一种预测结果的投注方式。投注的数量(注数)为1。
复式投注:彩民对于某些场次的比赛成绩选择两种以上的预测结果的投注方式。投注的数量为复式投注的组合数。例如,某彩民对一场比赛预测了两个结果(例如,胜平), 另一场比赛预测了三个结果(胜负平),其他比赛都只预测了一种结果,那么注数就是2×3 = 6。这样的一个复式投注,可以看成一个包含六种单式投注的集合。
我们现在考虑一个简化的模型。对于一轮比赛,彩民需要竞猜其中n场比赛的结果,每场比赛的胜负平都有一个概率p(i, r)。其中,i表示第i场比赛。r = 0, 1, 2,分别表示比赛结果的(主队)负、平、胜。p(i, r)则表示第i场比赛、结果为r的概率。此外,还有一个概率q(i, r),表示第i场比赛,投注购买结果为r的概率。
例如,如果q(1,0) = 0.5,我们可以知道第一场比赛有50%的投注会买主队输球。我们假设这n场比赛互不相关,即p(i, r)的结果不会受p(j, r’)的影响,q(i, r)的结果也不会受q(j, r’)的影响(r ≠ r’)。
输入描述
第一行四个整数n, N, M, U(n, U ≤ 104, N, M ≤ 109)。以下n行,每行六个实数。第i + 1行的六个实数为p(i, 0), p(i, 1), p(i, 2), q(i, 0), q(i, 1)和q(i, 2),用来描述第i场比赛的相关信息。其中,p(i, 0) + p(i, 1) + p(i, 2) = 1, q(i, 0) + q(i, 1) + q(i, 2) = 1, q(i, j) ≠ 0。
输出描述
一个实数,表示最大得奖金期望得自然对数
输出保留3位小数
示例1
输入:
1 10 10 1 0.3 0.2 0.5 0.7 0.2 0.1
输出:
1.609
C++14(g++5.4) 解法, 执行用时: 682ms, 内存消耗: 724K, 提交时间: 2020-06-09 09:28:56
#include<bits/stdc++.h> #define Tp template<typename Ty> #define Ts template<typename Ty,typename... Ar> #define Reg register #define RI Reg int #define Con const #define CI Con int& #define I inline #define W while #define N 10000 #define DB double using namespace std; int n,m,A,B;DB s[N+5][3],f[N+5]; int main() { RI i,j;DB x,y,z,u,v,w;scanf("%d%d%d%d",&n,&A,&B,&m); for(i=1;i<=n;++i) scanf("%lf%lf%lf%lf%lf%lf",&x,&y,&z,&u,&v,&w),x/=u,y/=v,z/=w, s[i][0]=log(max(x,max(y,z))),s[i][1]=log(x+y+z-min(x,min(y,z))),s[i][2]=log(x+y+z); for(i=1;i<=n;++i) for(j=m;j;--j) f[j]=max(s[i][0]+f[j],max(j>1?s[i][1]+f[j/2]:0,j>2?s[i][2]+f[j/3]:0)); DB ans=0;for(i=1;i<=m;++i) ans<f[i]&&(ans=f[i]); return printf("%.3lf",log(1.0*B/A)+ans),0; }
C++(clang++11) 解法, 执行用时: 527ms, 内存消耗: 768K, 提交时间: 2020-10-28 13:05:03
#include <bits/stdc++.h> using namespace std; const int Maxn=10001,MaxU=10001; double a,b,c,d,e,f,data[MaxU],cha[Maxn][4],tmp[3];; int n,M,N,U; int main(){ scanf("%d%d%d%d",&n,&N,&M,&U); for(int i=1;i<=n;i++){ scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f); tmp[0]=a/d; tmp[1]=b/e; tmp[2]=c/f; cha[i][1]=log(max(tmp[1],max(tmp[0],tmp[2]))); cha[i][2]=log(max(tmp[1]+tmp[0],max(tmp[1]+tmp[2],tmp[0]+tmp[2]))); cha[i][3]=log(tmp[1]+tmp[0]+tmp[2]); } for(int i=1;i<=n;i++) for(int j=U;j>=1;j--) for(int k=1;k<=3;k++) if(j/k>=1) data[j]=max(data[j],data[j/k]+cha[i][k]); printf("%.3lf",log(M)-log(N)+data[U]); return 0; }