BZOJ2306 [Ctsc2011]幸福路径[倍增]
这个有环的情况非常的讨厌,一开始想通过数学推等比数列的和,但是发现比较繁就不做了。
然后挖掘这题性质。
- 数据比较小,但是体力可以很接近1(恼怒),也就是说可能可以跳很多很多步。算了一下,大概跳了2e7次左右这个体力才缩到1e-14左右,这时已经几乎不会影响答案惹。也就是说,点比较少,有没有暴力做法?
- 发现从一个点假设满体力开始跳若干步,有最大价值的方案,如果前面一个点跳若干步过来,再在这个点以某个$x∈(0,1)$的体力开始,那么原来的最大的方案还是最大的,只要乘上一开始这个体力就好了。这说明答案可以用类似dp的方式逼近。
然后看这个跳非常多步还可以dp就反应到了倍增跳跃的模型。设$f[i][j][k]$为从$i$到$j$跳$2^k$步最大价值。然后可以倍增推了。
$f[i][j][k]=\max \{ f[i][l][k-1] + p^{2^{k-1}}*f[l][j][k-1] \} $
这个是$O(n^3 logn)$的,log那个是自己调的,25左右为宜。
由于是个人想的,所以实现上比较清奇。后来看了说本质就是个floyd。。感觉我理解还不够深入呃,如果谁知道为什么换一下枚举顺序就可以滚动了,烦请赐教。
另外有一个坑暂时不知道为什么,line34初始化要先给没有自环的连上自环,价值0。以后可能会请教别人这个地方,在座各位如果知道为什么这样还望不吝赐教。。
2019.9.29 UPD:从神仙hkk处获取了为什么要给所有点都连自环$0$:如果是下面这组数据:
0.5
hack!!
显然有问题。因为,这里的路是有尽头的,需要跳三步,而没办法有一个状态有效表示跳3步,不妨改变状态设计,设$f[i][j][k]$为从$i$到$j$跳最多$2^k$步最大价值。然后$f_{1,4,2}$就可以表示这个答案,而原来答案是没法表示的,但又因而引出这个$2^2$步的最后一步没办法再跳的问题,也就是在$4$号点没路了。这时候如果按照原来的dp方法,转移$f_{1,4,2}=f_{1,3,1}+p^2f_{3,4,1}$,但是这里的$f_{3,4,1}$按照新定义是可以有值的,如果直接用之前dp方程dp,会因为$f_{3,4,1}$没有值而出错,原因在于$f_{3,4,1}$最大时是$3\to 4$跳$2^0$步,满足新的定义,但是没法保留到$f_{3,4,1}$,这要求我们手动给$3$或者$4$添加一个0的自环保证可以按新定义正常转移。这样,就不会出现$2$的整数次方跳不完,后半截没有值而出错的情况。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<bitset>
#define dbg(x) cerr << #x << " = " << x <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=;
db f[N][N][];
db fp[],A[N],p,ans;
int n,m,s;
inline db fpow(db x,int k){db ret=;for(;k;k>>=,x*=x)if(k&)ret*=x;return ret;} int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);
read(n),read(m);
for(register int k=;k<=;++k)
for(register int i=;i<=n;f[i][i][k]=,++i)
for(register int j=;j<=n;++j)
f[i][j][k]=-0x3f3f3f3f;
for(register int i=;i<=n;++i)scanf("%lf",&A[i]);
read(s);scanf("%lf",&p);
for(register int i=;i<=;++i)fp[i]=fpow(p,<<i);
for(register int i=,x,y;i<=m;++i)read(x),read(y),f[x][y][]=A[y]*p;
for(register int k=;k<=;++k)
for(register int i=;i<=n;++i)
for(register int l=;l<=n;++l)
for(register int j=;j<=n;++j)
MAX(f[i][j][k],f[i][l][k-]+fp[k-]*f[l][j][k-]);
for(register int j=;j<=n;++j)MAX(ans,f[s][j][]);
ans+=A[s];printf("%.1lf\n",ans);
return ;
}
BZOJ2306 [Ctsc2011]幸福路径[倍增]的更多相关文章
- BZOJ2306:[CTSC2011]幸福路径(倍增Floyd)
Description 有向图 G有n个顶点 1, 2, …, n,点i 的权值为 w(i).现在有一只蚂蚁,从给定的起点 v0出发,沿着图 G 的边爬行.开始时,它的体力为 1.每爬过一条边,它 ...
- bzoj2306 [Ctsc2011]幸福路径 倍增 Floyd
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2306 题解 倍增 Floyd. 令 \(f[i][j][k]\) 表示走了 \(2^i\) 步 ...
- 【bzoj2306】[Ctsc2011]幸福路径 倍增Floyd
题目描述 一张n个点的有向图,每个点有一个权值.一开始从点$v_0$出发沿图中的边任意移动,移动到路径上的第$i$个点 输入 每一行中两个数之间用一个空格隔开. 输入文件第一行包含两个正整数 n, ...
- BZOJ2306: [Ctsc2011]幸福路径
Description 有向图 G有n个顶点 1, 2, -, n,点i 的权值为 w(i).现在有一只蚂蚁,从 给定的起点 v0出发,沿着图 G 的边爬行.开始时,它的体力为 1.每爬过一条 边,它 ...
- 【BZOJ2306】幸福路径(动态规划,倍增)
[BZOJ2306]幸福路径(动态规划,倍增) 题面 BZOJ 题解 不要求确切的值,只需要逼近 显然可以通过移动\(\infty\)步来达到逼近的效果 考虑每次的一步怎么移动 设\(f[i][j]\ ...
- 【BZOJ 2306】 2306: [Ctsc2011]幸福路径 (倍增floyd)
2306: [Ctsc2011]幸福路径 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 912 Solved: 437 Description 有向 ...
- [CTSC2011]幸福路径
题目描述 有向图 G有n个顶点 1, 2, …, n,点i 的权值为 w(i).现在有一只蚂蚁,从 给定的起点 v0出发,沿着图 G 的边爬行.开始时,它的体力为 1.每爬过一条 边,它的体力都会下降 ...
- BZOJ 2306: [Ctsc2011]幸福路径
Description 有向图 G有n个顶点 1, 2, -, n,点i 的权值为 w(i).现在有一只蚂蚁,从 给定的起点 v0出发,沿着图 G 的边爬行.开始时,它的体力为 1.每爬过一条 边,它 ...
- 「CTSC 2011」幸福路径
[「CTSC 2011」幸福路径 蚂蚁是可以无限走下去的,但是题目对于精度是有限定的,只要满足精度就行了. \({(1-1e-6)}^{2^{25}}=2.6e-15\) 考虑使用倍增的思想. 定义\ ...
随机推荐
- finereport 通过条件弹出 alert进行提示
function convertDateFromString(dateString) { if (dateString) { var date = new Date(dateString.replac ...
- 【C/C++】BOOST 线程完全攻略 - 基础篇
C++多线程开发是一个复杂的事情,mfc下提供了CWinThread类,和AfxBeginThread等等函数,但是在使用中会遇到很多麻烦事情,例如线程之间参数传递的问题,我们一般都是把参数new一个 ...
- 谈一谈 Normalize.css
Normalize.css是一种CSS reset的替代方案.它在默认的HTML元素样式上提供了跨浏览器的高度一致性.相比于传统的CSS reset,Normalize.css是一种现代的.为HTML ...
- 访问https接口报错 基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系
详细错误信息如下 请求错误信息:发生一个或多个错误.System.Net.Http.HttpRequestException: An error occurred while sending the ...
- luoguP1352没有上司的舞会(树形DP)
题目链接:https://www.luogu.org/problemnew/show/P1352 题意:给定n个结点,每个结点有一个权值,给n-1条边,n个结点构成一棵树.并且规定一个结点的父结点如果 ...
- 如何在java中去除中文文本的停用词
1. 整体思路 第一步:先将中文文本进行分词,这里使用的HanLP-汉语言处理包进行中文文本分词. 第二步:使用停用词表,去除分好的词中的停用词. 2. 中文文本分词环境配置 使用的HanLP-汉 ...
- kettle An error occurred, processing will be stopped: 错误 解决方法
上午在使用KETTLE时,报了一个 An error occurred, processing will be stopped: 错误,手动跑没有问题,用jekens调用就报错. 具体原因不清楚,后面 ...
- Redis 以及 Python操作Redis
Redis Redis是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis有以下特点: -- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可 ...
- Go语言流程控制中的break,continue和goto(七)
break(跳出循环) break用于跳出整个循环,如下: func main() { ;i<;i++{ { break } fmt.Println(i) } } // 0 1 2 3 代码里只 ...
- 友善的树形DP
一棵树,如果有序点对(x,y)之间路径的长度取模于3==0,那么ans0便加上这个长度: 如果取模于3==1,那么ans1便加上这个长度: 如果取模于3==2,那么ans2便加上这个长度: 让你求an ...