题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4418

Time travel

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
#### 问题描述
> Agent K is one of the greatest agents in a secret organization called Men in Black. Once he needs to finish a mission by traveling through time with the Time machine. The Time machine can take agent K to some point (0 to n-1) on the timeline and when he gets to the end of the time line he will come back (For example, there are 4 time points, agent K will go in this way 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, ...). But when agent K gets into the Time machine he finds it has broken, which make the Time machine can't stop (Damn it!). Fortunately, the time machine may get recovery and stop for a few minutes when agent K arrives at a time point, if the time point he just arrive is his destination, he'll go and finish his mission, or the Time machine will break again. The Time machine has probability Pk% to recover after passing k time points and k can be no more than M. We guarantee the sum of Pk is 100 (Sum(Pk) (1 If finishing his mission is impossible output "Impossible !" (no quotes )instead.

输入

There is an integer T (T <= 20) indicating the cases you have to solve. The first line of each test case are five integers N, M, Y, X .D (0< N,M <= 100, 0 <=X ,Y < 100 ). The following M non-negative integers represent Pk in percentile.

输出

For each possible scenario, output a floating number with 2 digits after decimal point

If finishing his mission is impossible output one line "Impossible !"

(no quotes )instead.

样例输入

2

4 2 0 1 0

50 50

4 1 0 2 1

100

样例输出

8.14

2.00

题意

一个人坐时光机,在时间轴上(0~n-1)来回运动,这个人向前运动k步的概率为p[k](k>=1&&k<=m),现在他要从X到Y,给你初始的X和初始运动方向,以及终点Y,问你他到终点时的期望步数。

题解

典型的dfs+高斯消元

首先我们可以把来回走拆成一条直线,如 0 1 2 可以拆成 0 1 2 1。这样就可以循环处理了。

然后dp[i]表示从i点到终点的期望步数,则有dp[i]=sigma(pro[x]*(dp[i+x]+x)),既sigma(pro[x]*dp[i+x])-dp[i]=-sigma(pro[x]*x)。列(n-1)*2个方程(只对那些起点可达的列方程),高斯求一下解就可以了。

代码

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII; const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-9;
const double PI = acos(-1.0); //start---------------------------------------------------------------------- const int maxn=233; typedef double Matrix[maxn][maxn]; ///n*(n+1)的增广矩阵
bool gauss_jordan(Matrix A,int n) {
int i,j,k,r;
for(i=0; i<n; i++) {
r=i;
for(j=i+1; j<n; j++) {
if(fabs(A[j][i])>fabs(A[r][i])) r=j;
}
if(fabs(A[r][i])<eps) continue;
if(r!=i) for(j=0; j<=n; j++) swap(A[r][j],A[i][j]); for(k=0; k<n; k++) if(k!=i) {
for(j=n; j>=i; j--) A[k][j]-=A[k][i]/A[i][i]*A[i][j];
}
} ///矛盾式
for(int i=n-1; i>=0&&fabs(A[i][i])<eps; i--) {
if(fabs(A[i][n])>eps) return false;
}
return true;
} Matrix A; int n,m,Y,X,D;
int arr[maxn];
double pro[maxn]; int tot;
void get_arr(){
tot=0;
if(X==0){
for(int i=0;i<n;i++) arr[tot++]=i;
for(int i=n-2;i>0;i--) arr[tot++]=i;
}else if(X==n-1){
for(int i=n-1;i>=0;i--) arr[tot++]=i;
for(int i=1;i<n-1;i++) arr[tot++]=i;
}else if(D==0){
for(int i=X;i<n;i++) arr[tot++]=i;
for(int i=n-2;i>=0;i--) arr[tot++]=i;
for(int i=1;i<X;i++) arr[tot++]=i;
}else{
for(int i=X;i>=0;i--) arr[tot++]=i;
for(int i=1;i<n;i++) arr[tot++]=i;
for(int i=n-2;i>X;i--) arr[tot++]=i;
}
} int vis[maxn];
bool flag=0;
void dfs(int u){
vis[u]=1;
if(arr[u]==Y) flag=true;
for(int i=1;i<=m;i++){
if(fabs(pro[i])<eps) continue;
int des=(u+i)%tot;
if(vis[des]) continue;
dfs(des);
}
} void init(){
clr(A,0);
clr(vis,0);
} int main() {
int tc;
scf("%d",&tc);
while(tc--){
scf("%d%d%d%d%d",&n,&m,&Y,&X,&D);
for(int i=1;i<=m;i++){
scf("%lf",&pro[i]); pro[i]/=100;
}
init();
get_arr(); flag=false;
dfs(0);
if(!flag){
prf("Impossible !\n");
continue;
} for(int i=0;i<tot;i++){
if(!vis[i]) continue;
if(arr[i]==Y){
A[i][i]=1.0;
continue;
}
A[i][i]=-1.0,A[i][tot]=0;
for(int j=1;j<=m;j++){
int des=(i+j)%tot;
A[i][des]+=pro[j];
A[i][tot]-=pro[j]*j;
}
} bool su=gauss_jordan(A,tot); if(!su||fabs(A[0][0])<eps) prf("Impossible !\n");
else prf("%.2lf\n",A[0][tot]/A[0][0]);
}
return 0;
} //end-----------------------------------------------------------------------

HDU 4418 Time travel 期望dp+dfs+高斯消元的更多相关文章

  1. luogu P4321 随机漫游 期望dp 二进制 高斯消元

    LINK:随机漫游 非常妙的一道题. 容易想到倒推期望. 设状态 f[i][j]表示到达第i个点 此时已经到达的集合为j能走到全集的期望边数. 只要求出来这个就能O(1)回答询问. \(f[i][j] ...

  2. hdu 4418 Time travel 概率DP

    高斯消元求期望!! 将n时间点构成2*(n-1)的环,每一点的期望值为dp[i]=dp[i+1]*p1+dp[i+2]*p2+……+dp[i+m]*pm+1. 这样就可以多个方程,利用高斯消元求解. ...

  3. 【 HDU 4936 】Rainbow Island (hash + 高斯消元)

    BUPT2017 wintertraining(15) #5B HDU - 4936 2014 Multi-University Training Contest 7 F 题意 直接看官方的题意和题解 ...

  4. BZOJ2707 [SDOI2012]走迷宫 【概率dp + tarjan + 高斯消元】

    题目 Morenan被困在了一个迷宫里.迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T.可惜的是,Morenan非常的脑小,他只会从一个点出发随机沿着一条从该点出发的 ...

  5. 【JLOI 2012】时间流逝(期望,树上高斯消元)

    题目链接 这是一道传统的期望题,可是有一些套路值得我去掌握. 我们用$s$来表示一种状态,就是当前拥有的能量圈,是一个正整数拆分的形式. 用$f_{s}$表示如果遇到果冻鱼后丢掉了最小的能量圈后的状态 ...

  6. hdu4418(概率dp + 高斯消元)

    应该是一个入门级别的题目. 但是有几个坑点. 1. 只选择x能到达的点作为guass中的未知数. 2. m可能大于n,所以在构建方程组时未知数的系数不能直接等于,要+= 3.题意貌似说的有问题,D为- ...

  7. BZOJ 2115 Wc2011 Xor DFS+高斯消元

    标题效果:鉴于无向图.右侧的每个边缘,求一个1至n路径,右上路径值XOR和最大 首先,一个XOR并能为一个路径1至n简单的路径和一些简单的XOR和环 我们开始DFS获得随机的1至n简单的路径和绘图环所 ...

  8. 【BZOJ 2337】 2337: [HNOI2011]XOR和路径(概率DP、高斯消元)

    2337: [HNOI2011]XOR和路径 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1170  Solved: 683 Description ...

  9. ACM学习历程—HDU 3915 Game(Nim博弈 && xor高斯消元)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3915 题目大意是给了n个堆,然后去掉一些堆,使得先手变成必败局势. 首先这是个Nim博弈,必败局势是所 ...

随机推荐

  1. Linux系统编译Openssl步骤

    参照:  https://blog.csdn.net/luckydog612/article/details/80396077 1.提前准备工作 去https://www.openssl.org网站下 ...

  2. 20155327 2017-2018-2 《Java程序设计》第一周学习总结

    20155327 2017-2018-2 <Java程序设计>第一周学习总结 教材学习内容总结 三大平台: 1.Java SE:JVM,JRE,JDK,java语言 JVM:Java虚拟机 ...

  3. python基础学习1-正则表达式

    #!/usr/bin/env python # -*- coding:utf-8 -*- import re print(re.findall('alex','yyyyabbblalexrrreooo ...

  4. C++实现tar包解析

    tar(tape archive)是Unix和类Unix系统上文件打包工具,可以将多个文件合并为一个文件,使用tar工具打出来的包称为tar包.一般打包后的文件名后缀为".tar" ...

  5. CF 1114 C. Trailing Loves (or L'oeufs?)

    C. Trailing Loves (or L'oeufs?) 链接 题意: 问n!化成b进制后,末尾的0的个数. 分析: 考虑十进制的时候怎么求的,类比一下. 十进制转化b进制的过程中是不断mod ...

  6. 洛咕 P2467 [SDOI2010]地精部落

    同波浪,简单dp. 高度从1到n插入山脉,设f[i][j][k]表示插入了i个山脉,组成了j段,边界上有k个山脉的方案数. 那么新插入的山脉只会:插入在边界上且自己是一段.插入在边界上且与最左边的段相 ...

  7. CS100.1x-lab0_student

    这是CS100.1x第一个提交的作业,是给我们测试用的.相关ipynb文件见我github.本来没什么好说的.我在这里简单讲一下,后面会更详细的讲解.主要分成5个部分. Part 1: Test Sp ...

  8. hdu1754 I Hate It(线段树单点更新,区间查询)

    传送门 有更新单个学生成绩和查询某个区间内学生成绩最大值两种操作 线段树代码 #include<bits/stdc++.h> using namespace std; +; using n ...

  9. pycharm专业版激活码

    K71U8DBPNE-eyJsaWNlbnNlSWQiOiJLNzFVOERCUE5FIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1lIjoiI ...

  10. Go简单聊天

    用Go简单实现网络通信 其余功能可以在这个模型上继续加,比如增加通信人数,实现聊天 server 端 package main import ( "fmt" "log&q ...