【题解】HDU4870 Rating

本文介绍了一种简洁的数学方法,利用动态规划解决分数打怪游戏,找到从0分到达20分的期望步数。通过递推公式推导出t[i+1]的表达式,并指出最后答案由t19和t20之和给出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

sol:
提供一种比较简洁和巧妙的做法(二维状态高斯消元就不说了吧 qwq)

题解在代码注释里了。

#include<bits/stdc++.h>
#define db double
using namespace std;
const int N=1e5+5;
//纯数学推导:
//设 dp[i] 表示当前分数为 i ,到达 20 的期望步数 
//根据定义得到 
//dp[0] = dp[0] * q + dp[1] * p + 1
//所以
//dp[0] = dp[1] + 1 / p
//同理 dp[1] = dp[0] * q + dp[2] * p + 1
//即 dp[1] = (dp[1] + 1) * q + dp[2] * p + 1
//所以 dp[0] = 1/{p^2} + 1/p + dp[2]
//以此类推,对于 0<i<=n ,都有 dp[0] = dp[i] + ti ,那么对于 i=n, 有 dp[i] = dp[i-2] * q + dp[i+1] * p + 1
//即 dp[0] - ti = (dp[0] - t_{i-2}) * q + dp[i+1] * p +1
//我们要研究的式子左边是 dp[0] ,而右边是系数为 1 的 dp[i+1] 和一个常数,所以移项可得:
//p * dp[0] = -t_{i-2} * q + ti + dp[i+1] * p + 1
//dp[0] = -t{i-2} * q / p + ti / p + 1/p + dp[i+1]
//所以 t{i+1} = -t{i-2} * q / p + ti / p + 1/p
//又很容易发现两个账号打的次数是可以分开算的,且最终状态一定一个为 19,另一个为 20,所以答案就是 t19 + t20
//当然其他换元的方法也能通过
//关键在于能否推出数列递推式(本质是数列 eg. ai = a_{i-1} +a_{i+1} 将下标进行加减就可以得到不带后效性的递推式 很神奇 qwq) 
db p,q,t[N];  
int main() {
	while(cin>>p) {
		q=1-p;
		t[1]=1.0/p;
		t[2]=1.0/p+1.0/(p*p);
		for(int i=2;i<20;i++) {
			t[i+1]=-t[i-2]*q/p+t[i]/p+1.0/p;
		}
		printf("%lf\n",t[19]+t[20]);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值