【CF553E】Kyoya and Train 最短路+cdq分治+FFT
【CF553E】Kyoya and Train
题意:有一张$n$个点到$m$条边的有向图,经过第i条边要花$c_i$元钱,经过第i条边有$p_{i,k}$的概率要耗时k分钟。你想从1走到n,但是如果整个过程耗时超过了$t$,则需要额外花费$f$元。求从1走到n的期望最小花费。
$n\le 50,m\le 100,t\le 20000,k\le 1$
题解:我们先用最短路预处理出如果已经超时了,从1走到n的最小花费。剩下的考虑DP。
用f[i][j]表示在i时刻到达了j,想走到n的最小花费。则对于第i条边$(a,b)$,我们有:
$f[a][j]=min(f[a][j],\sum f[b][j+k]p_{i,k})$
发现只有后面的时间会影响前面的时间,所以我们对时间进行cdq分治。再令g[i][j]表示在j时刻经过第i条边,想走到n的最小花费,那么对于边(a,b),我们可以用f[b]更新g[b],在用g[b]和f[a]取min即可。g[b]的转移如下:
$g[i][j]=\sum f[b][j+k]p_{i,k}$
你会发现这是一个卷积的形式,上fft即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define pi acos(-1.0)
using namespace std;
const int maxn=20010;
typedef double db;
struct cp
{
db x,y;
cp() {}
cp(db a,db b) {x=a,y=b;}
cp operator + (const cp &a) const {return cp(x+a.x,y+a.y);}
cp operator - (const cp &a) const {return cp(x-a.x,y-a.y);}
cp operator * (const cp &a) const {return cp(x*a.x-y*a.y,x*a.y+y*a.x);}
}l1[100010],l2[100010];
int head[60],next[110],to[110],pa[110],pb[110],pc[110],vis[60],dis[60];
db p[110][20010],F,f[60][20010],g[110][20010],sp[110][20010];
int n,m,T;
inline void FFT(cp *a,int len,int f)
{
int i,j,k,h;
cp t;
for(i=k=0;i<len;i++)
{
if(i>k) swap(a[i],a[k]);
for(j=len>>1;(k^=j)<j;j>>=1);
}
for(h=2;h<=len;h<<=1)
{
cp wn(cos(2*pi*f/h),sin(2*pi*f/h));
for(i=0;i<len;i+=h)
{
cp w(1,0);
for(j=i;j<i+h/2;j++) t=w*a[j+h/2],a[j+h/2]=a[j]-t,a[j]=a[j]+t,w=w*wn;
}
}
if(f==-1) for(i=0;i<len;i++) a[i].x/=len;
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
void solve(int l,int r)
{
if(l==r)
{
for(int i=1;i<n;i++) f[i][l]=1e9;
for(int i=1;i<=m;i++)
{
g[i][l]+=sp[i][T-l+1]*(dis[pb[i]]+F);
f[pa[i]][l]=min(f[pa[i]][l],g[i][l]+pc[i]);
}
return ;
}
int mid=(l+r)>>1,i,j,len;
for(len=1;len<r-l+r-mid;len<<=1);
solve(mid+1,r);
for(j=1;j<=m;j++)
{
memset(l1,0,sizeof(l1[0])*len),memset(l2,0,sizeof(l2[0])*len);
for(i=1;i<=r-l;i++) l1[r-l-i].x=p[j][i];
for(i=mid+1;i<=r;i++) l2[i-mid-1].x=f[pb[j]][i];
FFT(l1,len,1),FFT(l2,len,1);
for(i=0;i<len;i++) l1[i]=l1[i]*l2[i];
FFT(l1,len,-1);
for(i=0;i<mid-l+1;i++) g[j][l+i]+=l1[r-mid-1+i].x;
}
solve(l,mid);
}
int main()
{
//freopen("cf553E.in","r",stdin);
n=rd(),m=rd(),T=rd(),F=rd();
int i,j;
for(i=1;i<=m;i++)
{
pa[i]=rd(),pb[i]=rd(),pc[i]=rd();
for(j=1;j<=T;j++) p[i][j]=rd()*0.00001;
for(j=T;j;j--) sp[i][j]=sp[i][j+1]+p[i][j];
}
memset(dis,0x3f,sizeof(dis));
dis[n]=0;
for(i=1;i<=n;i++)
{
int k=0;
for(j=1;j<=n;j++) if(!vis[j]&&dis[j]<dis[k]) k=j;
vis[k]=1;
for(j=1;j<=m;j++) if(pb[j]==k) dis[pa[j]]=min(dis[pa[j]],dis[k]+pc[j]);
}
solve(0,T);
printf("%.10lf",f[1][0]);
return 0;
}
【CF553E】Kyoya and Train 最短路+cdq分治+FFT的更多相关文章
- [Codeforces 553E]Kyoya and Train(期望DP+Floyd+分治FFT)
[Codeforces 553E]Kyoya and Train(期望DP+Floyd+分治FFT) 题面 给出一个\(n\)个点\(m\)条边的有向图(可能有环),走每条边需要支付一个价格\(c_i ...
- 【BZOJ3456】轩辕朗的城市规划 无向连通图计数 CDQ分治 FFT 多项式求逆 多项式ln
题解 分治FFT 设\(f_i\)为\(i\)个点组成的无向图个数,\(g_i\)为\(i\)个点组成的无向连通图个数 经过简单的推导(枚举\(1\)所在的连通块大小),有: \[ f_i=2^{\f ...
- HDU - 5730 :Shell Necklace(CDQ分治+FFT)
Perhaps the sea‘s definition of a shell is the pearl. However, in my view, a shell necklace with n b ...
- [BZOJ 3456]城市规划(cdq分治+FFT)
[BZOJ 3456]城市规划(cdq分治+FFT) 题面 求有标号n个点无向连通图数目. 分析 设\(f(i)\)表示\(i\)个点组成的无向连通图数量,\(g(i)\)表示\(i\)个点的图的数量 ...
- 【uoj#244】[UER #7]短路 CDQ分治+斜率优化dp
题目描述 给出 $(2n+1)\times (2n+1)$ 个点,点 $(i,j)$ 的权值为 $a[max(|i-n-1|,|j-n-1|)]$ ,找一条从 $(1,1)$ 走到 $(2n+1,2n ...
- CF553E Kyoya and Train
Kyoya and Train 一个有\(n\)个节点\(m\)条边的有向图,每条边连接了\(a_i\)和\(b_i\),花费为\(c_i\). 每次经过某一条边就要花费该边的\(c_i\). 第\( ...
- BNUOJ 51279[组队活动 Large](cdq分治+FFT)
传送门 大意:ACM校队一共有n名队员,从1到n标号,现在n名队员要组成若干支队伍,每支队伍至多有m名队员,求一共有多少种不同的组队方案.两个组队方案被视为不同的,当且仅当存在至少一名队员在两种方案中 ...
- HDU 5730 Shell Necklace cdq分治+FFT
题意:一段长为 i 的项链有 a[i] 种装饰方式,问长度为n的相连共有多少种装饰方式 分析:采用dp做法,dp[i]=∑dp[j]*a[i-j]+a[i],(1<=j<=i-1) 然后对 ...
- HDU 5730 Shell Necklace(CDQ分治+FFT)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5730 [题目大意] 给出一个数组w,表示不同长度的字段的权值,比如w[3]=5表示如果字段长度为3 ...
随机推荐
- 手把手教你 Mockito 的使用
什么是 Mockito Mockito 是一个强大的用于 Java 开发的模拟测试框架, 通过 Mockito 我们可以创建和配置 Mock 对象, 进而简化有外部依赖的类的测试.使用 Mockito ...
- 27.移除元素(c++方法实现)
问题描述: 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间 ...
- C# CRC16 和汉明重量
最近在看redis之类的pdf,发现redis在做集群的时候,不同的key分到不同的主服务器,其中划分key的算法采用CRC16算法,所以特此整理一下其C#code如下: #region CRC16 ...
- TensorFlow进阶(二)---张量的操作
张量操作 在tensorflow中,有很多操作张量的函数,有生成张量.创建随机张量.张量类型与形状变换和张量的切片与运算 生成张量 固定值张量 tf.zeros(shape, dtype=tf.flo ...
- 如何去掉Autodesk教育版印戳
在打开一些CAD图形文件的时候,有时会遇到这样的提示: 当我们打印图形的时候,就会在标题栏显示"由Autodesk教育版产品生成",这个标题据说是用盗版CAD文件造成的,虽然我们用 ...
- Android架构初探
#一 背景点评美团合并之后,业务需要整合,我们部门的几条业务需要往美团平台迁移,为了降低迁移成本,开发和维护成本,以及将来可能要做的单元测试,需要对架构进行相应的调整.之前的代码都堆在Activity ...
- leetcode笔记:Validate Binary Search Tree
一. 题目描写叙述 Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is ...
- tmux入门
按键 man tmux和C+b?两个操作可以获得一切. C-b ? 显示快捷键帮助 C-b C-o 调换窗口位置,类似与vim 里的C-w C-b 空格键 采用下一个内置布局 C-b ! 把当前窗口变 ...
- JSOUP爬虫示例
利用JSOUP做爬虫,爬取我博客中的所有标题加链接,代码示例如下: package com.test.jsoup; import java.io.IOException; import org.jso ...
- 基于Centos搭建Laravel 环境搭建
系统要求:CentOS 7.2 64 位操作系统 安装 Laravel Laravel 简介 Laravel 是一套简洁.优雅的 PHP Web 开发框架.它可以让你从面条一样杂乱的代码中解脱出来:它 ...