●codeforces 553E Kyoya and Train
题链:
http://codeforces.com/problemset/problem/623/E
题解:
FFT,DP
题意:
一个有向图,给出每条边的起点u,终点v,费用c,以及花费每种时间的概率P[e][j](表示走第e条边花费时间为j的概率)
现在需要从1号点走到n号点,如果不能在T个单位时间内到达,则达到后还要另外支付X的费用。
求出所需支付的最小期望费用。
先是一个暴力的DP方法:
(考虑到每条边的耗时至少为1,可以把状态设为类似分层图的形式)
定义$F[i][t]$为$t$时刻在$i$点时,到达终点n所需要的最小期望费用。
不难得到DP转移,枚举每条i点的出边e:
$$F[i][t]=min(c[e]+\sum_{j=1}^{T}P[e][j]\times F[v[e]][t+j])$$
然后令$G[e][t]$表示$t$时刻从${u[e]}$出发到达n点所需要的最小期望费用。
即$$G[e][t]=c[e]+\sum_{j=1}^{T}P[e][j]\times F[v[e]][t+j]$$
所以$$F[i][t]=min(G[e][t])\quad (u[e]=i)$$
这个复杂度为$O(mT^2)$
考虑优化,注意到求G的式子有点像卷积的形式。
的确,我们只需要把$P[e]$数组翻转,即可得到:
$$G[e][t]=G'[e][T+t]=c[e]+\sum_{j=1}^{T}P[e][T-j]\times F[v[e]][t+j]$$
这个就可以用FFT做了。
但是我们并不知道P数组所有的值,又怎么办呢?
这时采用分治的方法,(类似CDQ那种)
基于这样一个事实:
$$D_r=\sum_{i=0}^{n-1}f_ig_{r-i}=\sum_{i=0}^{k}f_ig_{r-i}+\sum_{i=k+1}^{n-1}f_ig_{r-i}$$
用文字描述就是:计算卷积时,可以把贡献分成几段来分别计算,
或者说用FFT计算D的值时,可以先计算$\sum_{i=0}^{k}f_ig_{r-i}这个卷积,再加上\sum_{i=k+1}^{n-1}f_ig_{r-i}这个卷积$
所以我们对时间进行分治:
1.对于当前的分治层$t∈[l,r]$,我们先递归处理右边[mid,r],得到右边所有的F[i][mid~r],然后用FFT求值去贡献到G[e][l~mid-1]。
2.继续递归处理左边[l,mid-1]。
3.当到达递归最底层即$l=r$时,我们用G去求出所有的$F[i][l]$,因为此时的转移来源$G[e][t](t>l)$都计算完毕。
算法的大体流程就这样,复杂度$O(mTlog^2T)$
具体的实现还需特别注意:
1.FFT时的下标转化感觉有点绕,(我是膜的别人的做法)。
2.当t>给出的T时,由于已经超时,所以就直接按费用最短路前往n点。
3.由于每次求G[e][t]时,需要的来源状态的时间t'<=t+T,所以数组的时间那一维开为2*T即可。
代码:
#include<bits/stdc++.h>
#define MAXN 55
#define MAXM 105
#define MAXT 40005
using namespace std;
const double Pi=acos(-1);
struct Complex{
double real,image;
Complex(double _real=0,double _image=0):real(_real),image(_image){}
Complex operator - () const{return Complex(-real,-image);}
friend Complex operator + (const Complex &A,const Complex &B){return Complex(A.real+B.real,A.image+B.image);}
friend Complex operator - (const Complex &A,const Complex &B){return A+(-B);}
friend Complex operator * (const Complex &A,const Complex &B){return Complex(A.real*B.real-A.image*B.image,A.image*B.real+A.real*B.image);}
}A[65538],B[65538],nul(0,0);
double F[MAXN][MAXT],G[MAXM][MAXT],P[MAXM][MAXT];
int U[MAXM],V[MAXM],C[MAXM],S[MAXN][MAXN];
int order[65538];
int N,M,T,X;
void read(int &x){
static int sign; static char ch;
x=0; sign=1; ch=getchar();
while(ch<'0'||'9'<ch){if(ch=='-')sign=-1;ch=getchar();}
while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
x=x*sign;
}
void Floyd(){
memset(S,0x3f,sizeof(S));
for(int i=1;i<=N;i++) S[i][i]=0;
for(int e=1;e<=M;e++) S[U[e]][V[e]]=C[e];
for(int k=1;k<=N;k++)
for(int i=1;i<=N;i++) if(i!=k)
for(int j=1;j<=N;j++) if(j!=k&&j!=i)
S[i][j]=min(S[i][j],S[i][k]+S[k][j]); }
void FFT(Complex *Y,int n,int sign){
for(int i=0;i<n;i++) if(i<order[i]) swap(Y[i],Y[order[i]]);
for(int d=2;d<=n;d<<=1){
Complex dw(cos(2*Pi/d),sin(sign*2*Pi/d)),w,tmp;
for(int i=0;w=Complex(1,0),i<n;i+=d)
for(int k=i;k<i+d/2;w=w*dw,k++)
tmp=w*Y[k+d/2],Y[k+d/2]=Y[k]-tmp,Y[k]=Y[k]+tmp;
}
if(sign==-1) for(int i=0;i<n;i++) Y[i].real/=1.0*n;
}
void contribution(int l,int mid,int r){
static int m,n,len; m=r-l+1;
for(n=1,len=0;n<=m+r-mid;n<<=1) len++;
for(int i=1;i<n;i++) order[i]=(order[i>>1]>>1)|((i&1)<<(len-1));
for(int e=1;e<=M;e++){
for(int i=0;i<n;i++) A[i]=B[i]=nul;
for(int i=1;i<m;i++) B[i]=Complex(P[e][i],0);
for(int i=mid;i<=r;i++) A[r-i]=Complex(F[V[e]][i],0);
FFT(A,n,1); FFT(B,n,1);
for(int i=0;i<n;i++) A[i]=A[i]*B[i];
FFT(A,n,-1);
for(int i=l;i<mid;i++) G[e][i]+=A[r-i].real;
}
}
void solve(int l,int r){
if(l==r){
for(int i=1;i<N;i++) F[i][l]=S[i][N]+X;
for(int e=1;e<=M;e++)
F[U[e]][l]=min(F[U[e]][l],C[e]+G[e][l]);
return;
}
int mid=(l+r+1)/2;//向上取整
solve(mid,r);
contribution(l,mid,r);
solve(l,mid-1);
}
int main(){
read(N); read(M); read(T); read(X);
for(int e=1,x;e<=M;e++){
read(U[e]); read(V[e]); read(C[e]);
for(int i=1;i<=T;i++)
read(x),P[e][i]=1.0*x/100000;
}
Floyd();
for(int i=1;i<=N;i++)
for(int j=T+1;j<=2*T;j++)
F[i][j]=S[i][N]+X;
for(int j=1;j<=T;j++) F[N][j]=0;
contribution(0,T+1,2*T);
solve(0,T);
printf("%.8lf\n",F[1][0]);
return 0;
}
●codeforces 553E Kyoya and Train的更多相关文章
- [Codeforces 553E]Kyoya and Train(期望DP+Floyd+分治FFT)
[Codeforces 553E]Kyoya and Train(期望DP+Floyd+分治FFT) 题面 给出一个\(n\)个点\(m\)条边的有向图(可能有环),走每条边需要支付一个价格\(c_i ...
- CodeForces 553E Kyoya and Train 动态规划 多项式 FFT 分治
原文链接http://www.cnblogs.com/zhouzhendong/p/8847145.html 题目传送门 - CodeForces 553E 题意 一个有$n$个节点$m$条边的有向图 ...
- Codeforces 553E Kyoya and Train
题目大意 链接:CF533E 给一张\(n\)个点,\(m\)条边的图,起点\(1\)终点\(n\),如果不能在\(T\)的时间内到达则需支付\(X\)的代价. 走每条边都会支付一定代价,经过一条边\ ...
- CF 553E Kyoya and Train
题目分析 期望\(\text{dp}\). 设\(f_{i,j}\)表示在第\(j\)个时刻从\(i\)点出发,到达终点的期望花费. 有转移方程: \[ f_{x,t}=\min_{(x,y)\in ...
- 【codeforces 553E】 Kyoya and Train
http://codeforces.com/problemset/problem/553/E (题目链接) 艹尼玛,CF还卡劳资常数w(゚Д゚)w!!系统complex被卡TLE了T_T,劳资写了一天 ...
- 【CF553E】Kyoya and Train 最短路+cdq分治+FFT
[CF553E]Kyoya and Train 题意:有一张$n$个点到$m$条边的有向图,经过第i条边要花$c_i$元钱,经过第i条边有$p_{i,k}$的概率要耗时k分钟.你想从1走到n,但是如果 ...
- Codeforces A. Kyoya and Colored Balls(分步组合)
题目描述: Kyoya and Colored Balls time limit per test 2 seconds memory limit per test 256 megabytes inpu ...
- CF553E Kyoya and Train
Kyoya and Train 一个有\(n\)个节点\(m\)条边的有向图,每条边连接了\(a_i\)和\(b_i\),花费为\(c_i\). 每次经过某一条边就要花费该边的\(c_i\). 第\( ...
- codeforces 553A . Kyoya and Colored Balls 组合数学
Kyoya Ootori has a bag with n colored balls that are colored with k different colors. The colors are ...
随机推荐
- 201621123050 《Java程序设计》第7周学习总结
1. 本周学习总结 1.1 思维导图:Java图形界面总结 2.书面作业 1. GUI中的事件处理 1.1 写出事件处理模型中最重要的几个关键词. 1.事件:用户的操作,例如点击或输入之类的操作 2. ...
- 【iOS】跳转到设置页面
iOS8.0以后有效 定位服务 定位服务有很多APP都有,如果用户关闭了定位,那么,我们在APP里面可以提示用户打开定位服务.点击到设置界面设置,直接跳到定位服务设置界面.代码如下: 1 2 3 4 ...
- 关于Android 7.0(API24)相机的问题汇总
在开发Android项目的时候,我们会用到相机,有些时候只是开发一个普通的扫码,仅仅赋予一下 权限 就好了,但是有些时候是需要拍照和从相册中获取照片的.我们在Android 5.0以及5.0之前调用相 ...
- SAN LUN Mapping出错导致文件系统共享冲突,数据恢复成功
[用户单位] 中国联通某分公司[数据恢复故障描述] SUN 光纤存储系统,中心存储为6枚300G硬盘组成的RAID6,划分为若干LUN,MAP到不同业务的服务器上,服务器上运行SUN SOLAR ...
- 再议Python协程——从yield到asyncio
协程,英文名Coroutine.前面介绍Python的多线程,以及用多线程实现并发(参见这篇文章[浅析Python多线程]),今天介绍的协程也是常用的并发手段.本篇主要内容包含:协程的基本概念.协程库 ...
- 看漫画学Flux
原文地址:A cartoon guide to Flux - by Lin Clark Flux在目前web开发中最受欢迎也较不被人理解,本文会以简单易懂的方式解释它. 出现问题 首先,我要声明Flu ...
- 单点登录实现机制:桌面sso
参考链接,感谢作者:https://zm10.sm-tc.cn/?src=l4uLj8XQ0IiIiNGckZ2TkJiM0ZyQktCZlo2Mi5uNmp6S0I/QysrJyszPztGXi5K ...
- docker生态系统
我的docker学习笔记6-docker生态 1.镜像即应用 代码构建.持续集成和持续交付 DaoCloud.Quay.IO 2.催生容器托管caas服务 基 ...
- spring-oauth-server实践:access_token的有效期分析
1.access_token有效期检查 用expiration和new Date()比较!!!!!! 分析目标-->expiration什么时候设置,设置规则如何配置!!!!!!! 2.acce ...
- MySql入门(2-1)windows下安装mysql的两种方式
一.下载mysql 1.下载解压MySQL 登录oracle主页,需要用户名和口令: lshengqi@netease.com/1wsx**** 下载路径:: https://dev.mysql.co ...