博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces 553E Kyoya and Train
阅读量:6852 次
发布时间:2019-06-26

本文共 2632 字,大约阅读时间需要 8 分钟。

题目大意

链接:

给一张\(n\)个点,\(m\)条边的图,起点\(1\)终点\(n\),如果不能在\(T\)的时间内到达则需支付\(X\)的代价。

走每条边都会支付一定代价,经过一条边\(i\)的时间有\(p_{i,j}\)的概率为\(j\),最小化期望代价。

题目分析

暴力方法:期望DP

\(f_{i,j}\)表示在第\(j\)时刻,从\(i\)点出发,到达终点的期望花费,

设边为\(e\),边上两点为\(x,y\),边集为\(E\),则有

\[ f(x,t)=\min\limits_{e\in E}\{val_{e}+\sum_{i=1}^Tp_{e,i}\cdot f(y,t+i)\} \]

时间复杂度\(O(n\cdot T^2)\)

或许你会觉得这样转移有问题,因为这不是一个DAG图,

但是,由于没有负权环,一个点不可能回到它的祖先,所以我们可以当做DAG来处理。


现在想想怎么优化这个DP。

我们设\(g_{e,t}\)表示\(\sum\limits_{i=1}^Tp_{e,i}\cdot f(y,t+i)\),显然有

\[ f(x,t)=\min\{val_e+g(e,t)\} \]

我们可以利用分治。

如果要求出\(l\leq t\leq r\)的所有\(f(x,t)\)\(g(e,t)\),不妨设\(mid=l+r>>1\)

先求出\(mid<t\leq r\)\(f\),并用这些\(f\)去更新\(l\leq t\leq mid\)\(g\),然后递归下去即可。


(方法co自的博客)

对于\(g(e,t)\),我们可以考虑把它化为卷积的形式进行更新。

\(mid=mid+1\),对于\(g(e,mid-1)\),我们有\(g(e,mid-1)+=\sum\limits_{i=0}^{r-mid+1}p_{e,i+1}\cdot f(e,mid+i)\)

我们把\(f\)数组反转,\(g(e,mid-1)+=\sum\limits_{i=0}^{r-mid+1}p_{e,i+1}\cdot f(e,r-i)\)

在映射一下:\(g(e,mid-1)+=\sum\limits_{i=0}^{r-mid+1}p^{\prime}_{e,i}\cdot f^\prime(e,r-mid-i)\)

即:\(g(e,mid-x)+=\sum\limits_{i=0}^{r-mid+1}p^{\prime}_{e,i}\cdot f^\prime(e,r-(mid-x)-i-1)\)

\(ans(r-(mid-x)-1)\)来更新\(g(mid-x)\),即用\(ans(r-t-1)\)来更新\(g(t)\)

代码实现

#include
#include
#include
#include
#include
#include
#include
#define MAXN 1<<30typedef long long LL;const int N=100005;using namespace std;inline int Getint(){register int x=0,f=1;register char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}return x*f;}const double pi=acos(-1);struct Z{ double r,i; Z(double _r=0,double _i=0){r=_r,i=_i;} Z operator + (const Z &a)const{return Z(r+a.r,i+a.i);} Z operator - (const Z &a)const{return Z(r-a.r,i-a.i);} Z operator * (const Z &a)const{return Z(r*a.r-i*a.i,r*a.i+i*a.r);} Z operator / (const double &a)const{return Z(r/a,i/a);} Z operator /= (const double &a) {return *this=Z(r/a,i/a);}};void FFT(Z *a,int x,int K){ static int rev[N],lst; int n=1<
>1]>>1)|((i&1)<
=l;i--)g[j][i]+=a[r-i-1].r; }}void Binary(int l,int r){ if(l==r){ for(int i=1;i<=m;i++) f[s[i].x][l]=min(f[s[i].x][l],s[i].z+g[i][l]); return; } int mid=l+r>>1; Binary(mid+1,r); Cal(l,mid+1,r); Binary(l,mid);}int main(){ n=Getint(),m=Getint(),T=Getint(),X=Getint(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i^j)mp[i][j]=MAXN; for(int i=1;i<=m;i++){ int x=Getint(),y=Getint(),z=Getint(); s[i]=(node){x,y,z}; mp[x][y]=min(mp[x][y],1.0*z); for(int j=1;j<=T;j++)p[i][j]=(double)Getint()/100000; } Floyd(); for(int j=T+1;j<=2*T;j++)f[n][j]=X; for(int i=1;i

转载于:https://www.cnblogs.com/Emiya-wjk/p/10040948.html

你可能感兴趣的文章
测试并发应用(二)监控Phaser类
查看>>
云上游戏数据分析实践
查看>>
前端如何实现数据双向绑定
查看>>
视频码率那些事
查看>>
Android仿网易云音乐:留声机效果
查看>>
vue-cli项目升级webpack4踩坑
查看>>
Python爬虫框架,内置微博、自如、豆瓣图书、拉勾、拼多多等规则
查看>>
android View 的绘制流程
查看>>
怎么实现mybatis半自动化解耦!看看资深程序员怎么说
查看>>
一个能拖动,能调整大小,能更新bind值的vue指令-vuedragx
查看>>
记一次基于vue-cli的多页面应用配置
查看>>
适用于小程序的 ES6
查看>>
Ribbon使用方法
查看>>
【译】将 Android 项目迁移到 Kotlin 语言
查看>>
vue 项目打包部署,通过nginx 解决跨域问题
查看>>
LightKV-高性能key-value存储组件
查看>>
小程序
查看>>
ES6变量的解构赋值
查看>>
ansible自动化运维详细教程及playbook详解
查看>>
快速解决Dev c++无法调试
查看>>