【DP】AcWing 290. 坏掉的机器人
分析
这题不如说是一道数学题吧 hh。
考虑倒推,假设现在已经求出了第 行的结果 ,现在求第 行的结果,记为 ,那么递推式为:
递推的边界是第 行,此时的 值都是 。
写成 的矩阵就是(以 为例):
那么进行高斯消元并求出 即可。
当然,因为这个矩阵比较特殊,我们不需要而且也不能直接用普通的高斯消元(复杂度 ),注意到这个矩阵化成上三角矩阵的代价只需要 ,类似地,化为对角矩阵的代价也是 ,所以整个过程 即可完成。
这题有一个边界问题: 的情况,上面的递推式显然不正确,在原做法上修改过于复杂,所以我们将其作为一个小问题解决:
给你一个数轴,从 出发,问到点 的期望步数是多少?
那么我们有 ,化简得 ,首项自然是 ,故通项公式为 。
实现
主体部分 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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2021-03-04 【DP】斜率优化初步