【DP】AcWing 290. 坏掉的机器人

分析

这题不如说是一道数学题吧 hh。

考虑倒推,假设现在已经求出了第 i+1 行的结果 c,现在求第 i 行的结果,记为 y​,那么递推式为:

23y113y2=13c1+123ym13ym1=13cm+114ym+34ym114ym+1=14cj+1j[2,m1]

递推的边界是第 n 行,此时的 c 值都是 0

写成 m×m 的矩阵就是(以 m=3 为例):

(2313014341401323)(y1y2y3)=(13c1+114c2+113c3+1)

那么进行高斯消元并求出 y 即可。

当然,因为这个矩阵比较特殊,我们不需要而且也不能直接用普通的高斯消元(复杂度 O(n3)),注意到这个矩阵化成上三角矩阵的代价只需要 O(n),类似地,化为对角矩阵的代价也是 O(n),所以整个过程 O(n) 即可完成。

这题有一个边界问题:m=1 的情况,上面的递推式显然不正确,在原做法上修改过于复杂,所以我们将其作为一个小问题解决:

给你一个数轴,从 0 出发,问到点 i 的期望步数是多少?

那么我们有 yi=12(yi+yi1)+1,化简得 yi=yi1+2,首项自然是 0,故通项公式为 yi=2i。​

实现

主体部分 30 行,很短的 qwq~。

// Problem: 坏掉的机器人
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/description/292/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;

#define debug(x) cerr << #x << ": " << (x) << endl
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)

const int N=1010;

int n, m;
int tx, ty;
double y[N], c[N];

double w[N][N];
void get(){
	rep(j,1,m){
		if(j==1 || j==m) c[j]=1.0/3*c[j]+1;
		else c[j]=1.0/4*c[j]+1;
	}

	w[1][1]=2.0/3, w[1][2]=-1.0/3;
	w[m][m-1]=-1.0/3, w[m][m]=2.0/3;
	rep(i,2,m-1) w[i][i]=3.0/4, w[i][i-1]=w[i][i+1]=-1.0/4;
	rep(i,2,m){
		double k=w[i][i-1]/w[i-1][i-1];
		rep(j,i-1,i) w[i][j]-=k*w[i-1][j]; 
		c[i]-=k*c[i-1];
	}
	dwn(i,m-1,1){
		double k=w[i][i+1]/w[i+1][i+1];
		w[i][i+1]=0;
		c[i]-=k*c[i+1];
	} 
	rep(j,1,m) y[j]=c[j]/w[j][j], c[j]=y[j];
}

int main(){
	cin>>n>>m>>tx>>ty;
	rep(i,1,m) c[i]=0;
	
	int tot=n-tx;
	if(m==1) return printf("%.4lf\n", 2.0*tot), 0;
	while(tot--) get();
	printf("%.4lf\n", c[ty]);
	return 0;
}
posted @   HinanawiTenshi  阅读(63)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
历史上的今天:
2021-03-04 【DP】斜率优化初步
点击右上角即可分享
微信分享提示