CF24D Broken robot

题目背景

小小迪带你吃瓜

题目描述

给出一个 n×m 的矩阵区域,一个机器人初始在第 x 行第 y 列,每一步机器人会等概率 的选择停在原地,左移一步,右移一步,下移一步,如果机器人在边界则丌会往区域外移动, 问机器人到达最后一行的期望步数。

输入输出格式

输入格式:

第一行两个整数,分别表示 n 和 m。 第二行两个整数,分别表示 x 和 y

输出格式:

一个小数表示答案

输入输出样例

输入样例#1:

10 10
10 4
输出样例#1:

0.0000000000
输入样例#2:

10 14
5 14
输出样例#2:

18.0038068653

sol:肯定是dp辣,状态呼之欲出了,dp[i][j]表示从位置i,j到最后一行的期望步数
转移也十分容易(但是不能直接转移,因为是几个方程组,要用高斯消元解出来)
前面带-->表示这是用来消元的方程

dp[i][1]=1/3*(dp[i][1]+dp[i][2]+dp[i+1][1])+1 (1)
--> dp[i][1] - 1/3*dp[i][1] - 1/3*dp[i][2] = 1/3*dp[i+1][1]+1
dp[i][j]=1/4*(dp[i][j]+dp[i][j-1]+dp[i][j+1]+dp[i+1][j])+1 (2~m-1)
--> dp[i][j] - 1/4*dp[i][j] - 1/4*dp[i][j-1] - 1/4*dp[i][j+1] = 1/4*dp[i+1][j]+1
dp[i][m]=1/3*(dp[i][m]+dp[i][m-1]+dp[i+1][m])+1 (m)
--> dp[i][m]-1/3*dp[i][m]-1/3*dp[i][m-1] = 1/3*dp[i+1][m]+1

但是直接解是n3的,会T出屎,但是这个每行最多就3个不为0的系数,所以O(n)推过去,求出最后一个,在推回来即可
/*
dp[i][1]=1/3*(dp[i][1]+dp[i][2]+dp[i+1][1])+1 (1)
--> dp[i][1] - 1/3*dp[i][1] - 1/3*dp[i][2] = 1/3*dp[i+1][1]+1
dp[i][j]=1/4*(dp[i][j]+dp[i][j-1]+dp[i][j+1]+dp[i+1][j])+1 (2~m-1)
--> dp[i][j] - 1/4*dp[i][j] - 1/4*dp[i][j-1] - 1/4*dp[i][j+1] = 1/4*dp[i+1][j]+1
dp[i][m]=1/3*(dp[i][m]+dp[i][m-1]+dp[i+1][m])+1 (m)
--> dp[i][m]-1/3*dp[i][m]-1/3*dp[i][m-1] = 1/3*dp[i+1][m]+1
*/
#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
ll s=;
bool f=;
char ch=' ';
while(!isdigit(ch))
{
f|=(ch=='-'); ch=getchar();
}
while(isdigit(ch))
{
s=(s<<)+(s<<)+(ch^); ch=getchar();
}
return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
if(x<)
{
putchar('-'); x=-x;
}
if(x<)
{
putchar(x+''); return;
}
write(x/);
putchar((x%)+'');
return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=;
int X,Y;
double dp[N][N];
double a[N][N],b[N];
inline void Debug(int n)
{
int i,j;
for(i=;i<=n;i++)
{
for(j=;j<=n;j++) printf("%.3lf ",a[i][j]);
printf("%.3lf\n",b[i]);
}
}
inline void Gauss(int n)
{
int i;
double Div;
// Debug(n);
for(i=;i<=n;i++)
{
double Div=a[i][i];
a[i][i]/=Div; b[i]/=Div;
if(i==n) break;
a[i][i+]/=Div;
Div=a[i+][i]/a[i][i];
a[i+][i]-=Div*a[i][i];
a[i+][i+]-=Div*a[i][i+];
b[i+]-=Div*b[i];
}
for(i=n-;i>=;i--) b[i]-=b[i+]*a[i][i+];
}
int main()
{
int i,j,n,m;
R(n); R(m); R(X); R(Y);
for(i=;i<=m;i++) dp[n][i]=.;
for(i=n-;i>=X;i--)
{
if(m!=)
{
a[][]=./.; a[][]=-./.; b[]=./.*dp[i+][]+.;
}
else
{
a[][]=./.; b[]=./.*dp[i+][]+;
}
for(j=;j<m;j++)
{
a[j][j]=./.; a[j][j-]=-./.; a[j][j+]=-./.; b[j]=./.*dp[i+][j]+.;
}
if(m>)
{
a[m][m]=./.; a[m][m-]=-./.; b[m]=./.*dp[i+][m]+.;
}
Gauss(m);
for(j=;j<=m;j++) dp[i][j]=b[j];
}
printf("%.10lf\n",dp[X][Y]);
return ;
}
/*
input
10 10
10 4
output
0.0000000000 input
10 14
5 14
output
18.0038068653 input
2 1
1 1
output
2.0000000000
*/

 

codeforces24D的更多相关文章

随机推荐

  1. 深入源码理解ThreadLocal和ThreadLocalMap

    一.ThreadLoacl的理解: 官方的讲: ThreadLocal是一个本地线程副本变量工具类,主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰 通俗的讲: Thre ...

  2. 两个select之间的元素互相移动并保持顺序

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  3. ASP.NET Core MVC四种枚举绑定方式

    前言 本节我们来讲讲在ASP.NET Core MVC又为我们提供了哪些方便,之前我们探讨过在ASP.NET MVC中下拉框绑定方式,这节我们来再来重点看看枚举绑定的方式,充分实现你所能想到的场景,满 ...

  4. Python 学习 第十三篇:数据的读写-文件、DataFrame、json

    Python的文件是一个重要的对象,使用open()函数来打开文件,创建文件对象,进行文件的读写操作.当数据用于交换信息时,通常需要把数据保存为有格式的文本数据,可以保存为有特定的行分隔符和列分隔符的 ...

  5. 作为一个.NET开发者,怎么看待和选择层出不穷的新技术,新架构?

    经常在一些技术社区看到这些的问题,一个.NET开发者去求职,看到应聘的公司的技术栈还是比较老的ASP.NET WEBFORM的时候,希望了解未来会否使用ASP.NET MVC的时候,没有获得肯定答复, ...

  6. Python入门-函数

    定义:将一组语句的集合通过一个名字(函数名)封装起来,要先执行这个函数,只需要调用其函数名即可.特性:1.减少重复代码2.使程序变的可扩展3.使程序变的易维护 函数参数:形参和实参形参:位置参数,关键 ...

  7. DevOps工程师到底做些什么?

    我们之前已经听到很多谈论DevOps和DevOps世界的最新趋势的事情,但是就DevOps工程师本身,到底干些什么呢? 在最纯粹的存在形式上来说,DevOps工程师是为了加快开发和运营团队之间的交付效 ...

  8. C++诡异异常处理

    虽然现在C++头文件允许只编译一次,但仍然可能因为头文件引用引起问题,当出现:“构造函数初始值设定项列表只能在构造函数定义中使用”,可能的原因是头文件互相引用导致的. 出现“error LNK1120 ...

  9. 消除element.style { }

    1.在写前台页面时,我们会发现控制台里会自动出现一些样式覆盖掉我们定义的样式: 解决的办法: 把被覆盖的样式单独定义出来,并在样式后面加上 !important,表示高优先级.

  10. 为github添加ssh key

    用git关联github上的远程仓库前需要先为github添加ssh key 一.检查本机是否生成ssh key 本地查找.ssh文件,其中id_rsa.pub中的内容就是ssh key 二.为git ...