专栏文章
题解:AT_abc224_g [ABC224G] Roll or Increment
AT_abc224_g题解参与者 1已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @miqimy8b
- 此快照首次捕获于
- 2025/12/04 05:25 3 个月前
- 此快照最后确认于
- 2025/12/04 05:25 3 个月前
ABC224G.Roll or Increment
题意:
有一个 面的骰子,掷出 到 的概率相等。初始数字为 ,目标数字为 。有两种操作:
-
花费 ,使当前数字加一;
-
花费 ,重掷。
询问最优策略下到达 的期望花费。
解法:
由于操作 2 前的操作 1 是无效的,所以最优策略一定分为两部分:
- 一直进行操作 2 使当前数字距离 足够近(或在 且距离足够近时不进行操作 2);
- 一直进行操作 1 使当前数字到达 。
足够近的概念比较模糊,所以我们定义足够近为当前数字小于 且二者差小于等于 ,那么当数字落在区间 内时达到足够近条件,于是我们可以得到期望花费为 ,即 。
观察到这个式子里只有 未确定,且形式非常像均值不等式里的 ,故考虑使用均值不等式去掉 :
当 即 时取等。
但是发现在 或 时取等条件不能成立,由于 在前两个情况下在区间 具有单调性,所以将 或 算一下即可。
代码如下:
CPP#include<bits/stdc++.h>
using namespace std;
#define ld long double
ld n,s,t,a,b,ans;
inline ld cal(int k){
return 1.0*b*n/(k+1)+1.0*a*k/2.0;
}
int main(){
cin>>n>>s>>t>>a>>b;
ans=min(cal(0),cal(t-1));
if(s<=t)ans=min(ans,a*(t-s));
int mink=sqrtl(2.0*b*n/a)-1;
if(mink>=0 && mink<t)ans=min(ans,cal(mink));
if(mink-1>=0 && mink-1<t)ans=min(ans,cal(mink-1));
if(mink+1>=0 && mink+1<t)ans=min(ans,cal(mink+1));
printf("%.16Lf\n",ans);
return 0;
}
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...