-> 双倍经验:Game on Sum (Hard Version)
有
n " role="presentation" style="position: relative;"> 块方蛋糕,绝顶聪明的 Sight 和 Sirrel 决定将每块蛋糕都分成两块各自品尝。Sight 会依次将每块蛋糕分成两块,而 Sirrel 有m " role="presentation" style="position: relative;"> 次优先选择权。对于
n " role="presentation" style="position: relative;"> 轮操作,每一次 Sight 会先选择一块蛋糕,将它随意分成任意大小分配的两块(可以是实数);如果 Sirrel 还有剩余的优先选择权,她可以选择一块,否则由 Sight 优先选择。最终两人都希望自己得到的蛋糕总量最大,求 Sight 能得到的最大蛋糕总和。
n ≤ 2500 , A i ≤ 5 × " role="presentation" style="position: relative;">。 10 4
由于优先选择权在 Sirrel 手里,我们不妨以她作为主视角考虑问题。而且如果以 Sight 的视角来看,直接由方程解出的
因此,设
- 如果使用了一次选择权,收益为
f i − 1 , j − 1 + x " role="presentation" style="position: relative;">; - 如果没有使用,收益为
f i − 1 , j + A i − x " role="presentation" style="position: relative;">。
那么综合收益为
那么如果可爱邪恶的 Sight 要让她尽可能收益少,就需要让两者相等。则收益为
直接 DP 就行啦!。。?真的吗?
发现可爱邪恶的 Sight 会先切大小较小的蛋糕,这会让爱可爱的 Sirrel 更加为难。先排序。
- #define Maxn 2505
- int n,m;
- double a[Maxn],sum[Maxn],f[Maxn][Maxn];
- bool cmp(double x,double y){ return x>y; }
- int main()
- {
- n=rd(),m=rd();
- for(int i=1;i<=n;i++) scanf("%lf",&a[i]);
- sort(a+1,a+n+1,cmp);
- for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
- for(int i=1;i<=n;i++)
- {
- f[i][0]=0,f[i][i]=sum[i]/2.0;
- for(int j=1;jfmax((f[i-1][j]+f[i-1][j-1]+a[i])/2.0,f[i-1][j]);
- }
- printf("%.6lf\n",sum[n]-f[n][m]);
- return 0;
- }
