【noi2019集训题1】 脑部进食 期望dp+高斯消元
题目大意:有n个点,m条有向边,每条边上有一个小写字母。
有一个人从1号点开始在这个图上随机游走,游走过程中他会按顺序记录下走过的边上的字符。
如果在某个时刻,他记录下的字符串中,存在一个子序列和S2相同,或者存在一个子串和S1相同,那么他就会当场去世。
他想知道他会不会当场去世,如果会,他想问你当场去世的时间的期望。
数据范围:n≤20,|S1|≤10,|S2|≤50
我们考虑列一个dp方程出来
设f[i][j][k]表示这人从1号点出发,当前走到i号点,且子串覆盖了S1的前j位,覆盖了S2的前k位的期望步数
然后你会发现你做不出来,因为最终根本无法统计答案(然后你就进死胡同了)
我们尝试把整个方程反过来
设$f[i][j][k]$表示你从$i$号点出发,之前走的路已经覆盖了$S1$的前$j$位,$S2$串的前$k$位的情况下,期望走多少部后会去世。
最终需要求的答案显然是$f[1][0][0]$
我们不难列出$f[i][j][k]=1+\frac{1}{d[i]} \sum\limits_{(i,u)∈E}f[u][j'][k']$
其中$d[i]$表示$i$号点的出度,$E$表示边集,$j'$和$k'$的具体值视该转移边的字母而订,非常好求。
这个方程我们显然可以通过高斯消元求解,时间复杂度$O(n^3|S1|^3|S2|^3)$,愉快$TLE$
无解的情况出现即为某一条方程出现了被零除。
我们发现,从$f[i][j'][k']$向$f[i][j][k]$转移的过程中,有$k'≥k$
那么我们显然可以固定$k$,对每一个$k$做一次高斯消元,然后向下一层传值,再高斯消元即可。
时间复杂度于是就降低到$O(n^3|S1|^3|S2|)$了
看起来有$4$个亿
实际上因不明原因,每一层需要转移的节点数根本就去不到理论上届
所以只跑了不到$20ms$(大雾)
#include<bits/stdc++.h>
#define M 205
#define eps 1e-6
using namespace std; double f[M][M]={},ans[M]={}; void gauss(int n){
for(int i=;i<=n;i++){
int id=i;
for(int j=i;j<=n;j++) if(f[id][i]<f[j][i]) id=j;
swap(f[i],f[id]);
if(fabs(f[i][i])<eps) {printf("-1\n"); exit();}
for(int j=i+;j<=n;j++){
double cha=f[j][i]/f[i][i];
for(int k=i;k<=n+;k++) f[j][k]-=f[i][k]*cha;
}
}
for(int i=n;i;i--){
for(int j=i+;j<=n;j++) f[i][n+]-=ans[j]*f[i][j];
ans[i]=f[i][n+]/f[i][i];
}
} struct edge{int u,next;char v;}e[]={}; int head[M]={},use=;
void add(int x,int y,char z){use++;e[use].u=y;e[use].v=z;e[use].next=head[x];head[x]=use;}
int n,m; char w[M]={},p[M]={}; int lenw,lenp;
int nxt[M]={}; void upd(char C,int id,int &nowj,int &nowk){
for(;nowj&&w[nowj+]!=C;nowj=nxt[nowj]);
if(w[nowj+]==C) nowj++;
if(p[nowk+]==C) nowk++;
} int vis[][][]={};
void dfs(int i,int j,int k){
if(vis[i][j][k]) return;
vis[i][j][k]=;
if(j==lenw||k==lenp) return;
for(int l=head[i];l;l=e[l].next){
char C=e[l].v; int id=e[l].u;
int nowj=j,nowk=k;
upd(C,id,nowj,nowk);
dfs(id,nowj,nowk);
}
} int id[][]={},iid[][]={},cnt=; double d[M]={}; int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
int x,y; char z[]; scanf("%d%d%s",&x,&y,z);
add(x,y,z[]); d[x]++;
}
scanf("%s",w+); lenw=strlen(w+);
scanf("%s",p+); lenp=strlen(p+);
for(int i=,j=;i<=n;i++){
for(;j&&w[j+]!=w[i];j=nxt[j]);
if(w[j+]==w[i]) j++;
nxt[i]=j;
}
dfs(,,);
for(int k=lenp-;~k;k--){
int cnt=;
for(int i=;i<=n;i++)
for(int j=;j<lenw;j++){
id[i][j]=;
if(vis[i][j][k])
id[i][j]=++cnt;
}
memset(f,,sizeof(f));
for(int i=;i<=n;i++)
for(int j=;j<lenw;j++) if(id[i][j]){
int ID=id[i][j];
f[ID][ID]=d[i];
f[ID][cnt+]=d[i];
for(int l=head[i];l;l=e[l].next){
char C=e[l].v; int u=e[l].u;
int nowj=j,nowk=k;
upd(C,u,nowj,nowk);
if(nowj==lenw) continue;
if(nowk==k){
f[ID][id[u][nowj]]--;
}else{
f[ID][cnt+]+=ans[iid[u][nowj]];
}
}
}
memcpy(iid,id,sizeof(id));
memset(ans,,sizeof(ans));
gauss(cnt);
}
printf("%.10lf\n",ans[]);
}
【noi2019集训题1】 脑部进食 期望dp+高斯消元的更多相关文章
- BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元
BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元 题意: 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机 ...
- 期望dp+高斯消元优化——uvalive4297好题
非常好的题!期望+建矩阵是简单的,但是直接套高斯消元会T 所以消元时要按照矩阵的形态 进行优化 #include<bits/stdc++.h> using namespace std; ; ...
- 2014多校第一场J题 || HDU 4870 Rating(DP || 高斯消元)
题目链接 题意 :小女孩注册了两个比赛的帐号,初始分值都为0,每做一次比赛如果排名在前两百名,rating涨50,否则降100,告诉你她每次比赛在前两百名的概率p,如果她每次做题都用两个账号中分数低的 ...
- ZJUT 1423 地下迷宫(期望DP&高斯消元)
地下迷宫 Time Limit:1000MS Memory Limit:32768K Description: 由于山体滑坡,DK被困在了地下蜘蛛王国迷宫.为了抢在DH之前来到TFT,DK必须尽快走 ...
- HDU4418 Time travel(期望dp 高斯消元)
题意 题目链接 Sol mdzz这题真的太恶心了.. 首先不难看出这就是个高斯消元解方程的板子题 \(f[x] = \sum_{i = 1}^n f[to(x + i)] * p[i] + ave\) ...
- HDU 2262 Where is the canteen 期望dp+高斯消元
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2262 Where is the canteen Time Limit: 10000/5000 MS ...
- hdu4418 Time travel 【期望dp + 高斯消元】
题目链接 BZOJ4418 题解 题意:从一个序列上某一点开始沿一个方向走,走到头返回,每次走的步长各有概率,问走到一点的期望步数,或者无解 我们先将序列倍长形成循环序列,\(n = (N - 1) ...
- LightOJ 1151 Snakes and Ladders 期望dp+高斯消元
题目传送门 题目大意:10*10的地图,不过可以直接看成1*100的,从1出发,要到达100,每次走的步数用一个大小为6的骰子决定.地图上有很多个通道 A可以直接到B,不过A和B大小不确定 而且 ...
- P4457-[BJOI2018]治疗之雨【期望dp,高斯消元】
正题 题目链接:https://www.luogu.com.cn/problem/P4457 题目大意 开始一个人最大生命值为\(n\),剩余\(hp\)点生命,然后每个时刻如果生命值没有满那么有\( ...
随机推荐
- SQL语言的分类(DQL、DML、DDL、DCL的概念与区别)
SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL. 1. 数据查询语言DQL数据查询语言DQL基本结构是由SELECT子句,FROM子句,WHER ...
- 【转】那些年用过的Redis集群架构(含面试解析)
引言 今天是2019年2月12号,也就是大年初八,我接到了高中同学刘有码面试失利的消息. 他面试的时候,身份是某知名公司的小码农一枚,却因为不懂自己生产上Redis是如何部署的,导致面试失败! 人间惨 ...
- LeetCode 442. 数组中重复的数据(Find All Duplicates in an Array) 17
442. 数组中重复的数据 442. Find All Duplicates in an Array 题目描述 Given an array of integers, 1 ≤ a[i] ≤ n (n ...
- 2019ICPC南昌现场赛总结
非常可惜的一场比赛,多了60分钟罚时与银牌无缘.今年6场ICPC网络赛里面打的最差的就是南昌站,冥冥之中自有天意吧,最后被安排去了南昌. 开场被队友叫去先看的L,说是足球,发现就是简单模拟,就直接上机 ...
- python 之 前端开发( JavaScript变量、数据类型、内置对象、运算符、流程控制、函数)
11.4 JavaScript 11.41 变量 1.声明变量的语法 // 1. 先声明后定义 var name; // 声明变量时无需指定类型,变量name可以接受任意类型 name= " ...
- h5开发微信公众号重定向到关注页面没有关注按钮 (微信你个坑)
搜索微信公众号是这样的 微信公众号重定向到关注页面没有关注按钮 如何微信公众号重定向到关注页面没有关注按钮,请看上篇笔记 无解,微信一直在封这种通过链接跳转到公众号关注页面的方法.只有放个二维码提示长 ...
- PowerShell自动部署ASP.NET Core程序到 IIS
Windows PowerShell 是一种命令行外壳程序和脚本环境,使命令行用户和脚本编写者可以利用 .NET Framework的强大功能.有关于更多PowerShell的信息,可参阅百度词条 接 ...
- FPS 游戏实现GDI透视
FPS游戏可以说一直都比较热门,典型的代表有反恐精英,穿越火线,绝地求生等,基本上只要是FPS游戏都会有透视挂的存在,而透视挂还分为很多种类型,常见的有D3D透视,方框透视,还有一些比较高端的显卡透视 ...
- 字节数组(byte[])与16进制字符串转换
/// <summary> /// 转换扩展类 /// </summary> public static class ConvertExtend { /// <summa ...
- 今天还是python游戏
话不多说,上源码: import random, pygame, sys from pygame.locals import * FPS = 30 # frames per second, the g ...