题意
你有 $A$ 个原料,每 $B$ 个合成一个产品。每一次合成你可以选择下列两种 $buff$ 的任意一种:
1 $P$% 的概率合成双倍产物
2 $Q$% 的概率返还一个原料
求期望最多合成多少产物。
思路
设 $dp(i)$ 表示还剩下 $i$ 个原料时的最大期望。
当$B\geqslant 2$时,
$$ \displaystyle dp[i]=max\begin{cases} P\times (dp[i-B]+2) + (1-P)\times (dp[i-B]+1), \\\\ Q\times (dp[i-B+1]+1) +(1-Q)\times (dp[i-B]+1). \end{cases} $$
当$B=1$时,
选择第一种方法:$dp[i]=P\times (dp[i-1]+2)+(1-P)\times (dp[i-1]+1)$
选择第二种方法(代入上面的式子,发现存在自环依赖
,左边有$dp[i]$,右边也有$dp[i]$,需要整理表达式):
$dp[i]=Q\times (dp[i]+1) +(1-Q)\times (dp[i-1]+1)$
$dp[i]=Q\times dp[i]+Q+(1-Q)\times dp[i-1] +(1-Q)$
$(1-Q)\times dp[i]=(1-Q)\times dp[i-1] +1$
$dp[i]=dp[i-1] +\frac{1}{1-Q}$
由上述式子得(已知$dp[0]=0$): $dp[i]=dp[0]+i\times d=0+i\times \frac{1}{1-Q}=\frac{i}{1-Q}$
两者取最大值
即可.
代码
// Problem: F. Timaeus
// Contest: Codeforces - 2023 Jiangsu Collegiate Programming Contest, 2023 National Invitational of CCPC (Hunan), The 13th Xiangtan Collegiate Programming Contest
// URL: https://codeforc.es/gym/104396/problem/F
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// Date: 2023-05-31 08:20:54
/**
* @author : SDTBU_LY
* @version : V1.0.0
* @上联 : ac自动机fail树上dfs序建可持久化线段树
* @下联 : 后缀自动机的next指针DAG图上求SG函数
**/
#include<iostream>
#include<cstring>
#include<algorithm>
#define MAXN 1000010
using namespace std;
typedef long long ll;
int A,B;
double P,Q;
double dp[MAXN];
int main()
{
// ios::sync_with_stdio(false);
// cin.tie(0),cout.tie(0);
cin >> A >> B >> P >> Q;
P/=100,Q/=100;
if(B==1)
{
for(int i=1;i<=A;i++)
dp[i]=max(P*(dp[i-1]+2)+(1-P)*(dp[i-1]+1),i/(1-Q));
}
else
for(int i=B;i<=A;i++)
dp[i]=max(P*(dp[i-B]+2)+(1-P)*(dp[i-B]+1),Q*(dp[i-B+1]+1)+(1-Q)*(dp[i-B]+1));
printf("%.15f\n",dp[A]);
return 0;
}
厉害呀,正式赛的时候就没想到这个,是怎么想到动态规划的呀,还有那个自环依赖是什么
左边的dp[i]带入式子后,右边也有dp[i],直接带入会影响后面的计算