BZOJ4899: 记忆的轮廓【概率期望DP】【决策单调性优化DP】
Description
通往贤者之塔的路上,有许多的危机。
我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增,
在[1,n]中,一共有n个节点。我们把编号在[1,n]的叫做正确节点,[n+1,m]的叫做错误节点。一个叶子,如果是正
确节点则为正确叶子,否则称为错误叶子。莎缇拉要帮助昴到达贤者之塔,因此现在面临着存档位置设定的问题。
为了让昴成长为英雄,因此一共只有p次存档的机会,其中1和n必须存档。被莎缇拉设置为要存档的节点称为存档
位置。当然不能让昴陷入死循环,所以存档只能在正确节点上进行,而且同一个节点不能存多次档。因为通往贤者
之塔的路上有影响的瘴气,因此莎缇拉假设昴每次位于树上一个节点时,都会等概率选择一个儿子走下去。每当走
到一个错误叶子时,再走一步就会读档。具体的,每次昴到达一个新的存档位置,存档点便会更新为这个位置(假
如现在的存档点是i,现在走到了一个存档位置j>i,那么存档点便会更新为j)。读档的意思就是回到当前存档点
。初始昴位于1,当昴走到正确节点n时,便结束了路程。莎缇拉想知道,最优情况下,昴结束路程的期望步数是多
少?
Input
第一行一个正整数T表示数据组数。
接下来每组数据,首先读入三个正整数n,m,p。
接下来m-n行,描述树上所有的非正确边(正确边即连接两个正确节点的边)
用两个正整数j,k表示j与k之间有一条连边,j和k可以均为错误节点,也可以一个为正确节点另一个为错误节点。
数据保证j是k的父亲。
50<=p<=n<=700,m<=1500,T<=5。
数据保证每个正确节点均有至少2个儿子,至多3个儿子。
Output
T行每行一个实数表示每组数据的答案。请保留四位小数。
Sample Input
1
3 7 2
1 4
2 5
3 6
3 7
Sample Output
9.0000
思路
发现其实还是在一条链上进行dp,剩下的分支都可以直接与处理做掉
首先求出从每个点进入坏点返回存档点的期望步数\(f_{i}\)
然后可以算一下以每一个点i为最新存档点到点j的期望步数(途中没有存档点)\(w_{i,j}\)
首先设\(cur\)为从\(j-1\)到\(j\)的期望步数
可以得到\(cur=\frac{1}{d_{j-1}}+\frac{d_{j-1}-1}{d_{j-1}}*(f_{j-1}+w_{i,j-1}+cur)\)
又因为\(w_{i,j}=w_{i,j-1}+cur\)
所以\(w_{i,j}=w_{i,j-1} * d_{j-1} + f_{j-1} * (d_{j-1} - 1) + 1\)
然后就可以dp了
记录\(dp_{i,j}\)表示前i个点选了j个存档位置,最新的存档位置是i的最小期望步数
我们想用决策单调性优化,所以就要从
\(dp_{j,x}+w_{j,i}\le dp_{k,x}+w_{k,i}(k<j)\)
推到
\(dp_{j,x}+w_{j,i+1}\le dp_{k,x}+w_{k,i+1}(k<j)\)
也就是说要证明\(w_{k,i}-w_{j,i}\le w_{k,i+1}-w_{j,i+1}\)
转化成\(w_{k,i}+w_{j,i+1}\le w_{k,i+1}+w_{j,i}\)
其中\(k<j\le i<i+1\)
然后对于w
我们来推一下式子看看是不是
\(w_{i,j}+w_{i+1,j+1}\le w_{i+1,j}+w_{i,j+1}\)
左边\(w_{i,j}+w_{i+1,j+1}=w_{i,j}+w_{i+1,j}*d_j+f_j*(d_j-1)+1\)
右边\(w_{i+1,j}+w_{i,j+1}=w_{i+1,j}+w_{i,j}*d_j+f_j*(d_j-1)+1\)
发现是满足的,然后就直接按照套路维护就可以了
#include <bits/stdc++.h>
using namespace std;
typedef long double ld;
const int N = 2010;
int n, m, p, d[N];
vector<int> g[N];
ld f[N], w[N][N], dp[N][N];
struct Node {
int pos, l, r;
Node() {}
Node(int pos, int l, int r): pos(pos), l(l), r(r) {}
} que[N];
void init() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
w[i][j] = 0;
dp[i][j] = 1e9;
}
}
for (int i = 1; i <= m; i++) {
f[i] = 0;
d[i] = 0;
g[i].clear();
}
}
void dfs(int u) {
if (!(signed) g[u].size()) {
f[u] = 1;
return;
}
for (int i = 0; i < (signed) g[u].size(); i++) {
int v = g[u][i];
dfs(v);
f[u] += (f[v] + 1.0) / (1.0 * d[u]);
}
}
ld calc(int i, int j, int k) {
return dp[j][k - 1] + w[j][i];
}
int find(Node a, int b, int k) {
int l = a.l, r = n, res = n;
while (l <= r) {
int mid = (l + r) >> 1;
if (calc(mid, a.pos, k) >= calc(mid, b, k)) res = mid, r = mid - 1;
else l = mid + 1;
}
return res;
}
void solve() {
scanf("%d %d %d", &n, &m, &p); p--;
init();
for (int i = 1; i <= m - n; i++) {
int u, v; scanf("%d %d", &u, &v);
g[u].push_back(v);
++d[u];
}
for (int i = n; i >= 1; i--) dfs(i);
for (int i = 1; i <= n - 1; i++) ++d[i];
for (int i = n; i >= 1; i--) {
for (int j = i + 1; j <= n; j++) {
w[i][j] = w[i][j - 1] * d[j - 1] + f[j - 1] * (d[j - 1] - 1) + 1;
}
}
dp[1][1] = 0;
for (int i = 2; i <= p; i++) {
int ql = 1, qr = 1;
que[ql] = Node(i - 1, i - 1, n);
for (int j = i; j < n; j++) {
if (ql <= qr && ++que[ql].l > que[ql].r) ql++;
dp[j][i] = calc(j, que[ql].pos, i);
if (ql <= qr && calc(n, que[qr].pos, i) <= calc(n, j, i)) continue;
while (ql <= qr && calc(que[qr].l, que[qr].pos, i) >= calc(que[qr].l, j, i)) qr--;
if (ql > qr) {
que[++qr] = Node(j, j, n);
} else {
int cur = find(que[qr], j, i);
que[qr].r = cur - 1;
que[++qr] = Node(j, cur, n);
}
}
}
ld ans = 1e9;
for (int i = 1; i < n; i++) {
ans = min(ans, dp[i][p] + w[i][n]);
}
printf("%.4Lf\n", ans);
}
int main() {
#ifdef dream_maker
freopen("input.txt", "r", stdin);
#endif
int T; scanf("%d", &T);
while (T--) solve();
return 0;
}
BZOJ4899: 记忆的轮廓【概率期望DP】【决策单调性优化DP】的更多相关文章
- 决策单调性优化dp 专题练习
决策单调性优化dp 专题练习 优化方法总结 一.斜率优化 对于形如 \(dp[i]=dp[j]+(i-j)*(i-j)\)类型的转移方程,维护一个上凸包或者下凸包,找到切点快速求解 技法: 1.单调队 ...
- Lightning Conductor 洛谷P3515 决策单调性优化DP
遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...
- CF868F Yet Another Minimization Problem 分治决策单调性优化DP
题意: 给定一个序列,你要将其分为k段,总的代价为每段的权值之和,求最小代价. 定义一段序列的权值为$\sum_{i = 1}^{n}{\binom{cnt_{i}}{2}}$,其中$cnt_{i}$ ...
- 2018.09.28 bzoj1563: [NOI2009]诗人小G(决策单调性优化dp)
传送门 决策单调性优化dp板子题. 感觉队列的写法比栈好写. 所谓决策单调性优化就是每次状态转移的决策都是在向前单调递增的. 所以我们用一个记录三元组(l,r,id)(l,r,id)(l,r,id)的 ...
- [BZOJ4850][JSOI2016]灯塔(分块/决策单调性优化DP)
第一种方法是决策单调性优化DP. 决策单调性是指,设i>j,若在某个位置x(x>i)上,决策i比决策j优,那么在x以后的位置上i都一定比j优. 根号函数是一个典型的具有决策单调性的函数,由 ...
- BZOJ2216 Poi2011 Lightning Conductor 【决策单调性优化DP】
Description 已知一个长度为n的序列a1,a2,...,an. 对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt( ...
- [NOI2009]诗人小G(dp + 决策单调性优化)
题意 有一个长度为 \(n\) 的序列 \(A\) 和常数 \(L, P\) ,你需要将它分成若干段,每 \(P\) 一段的代价为 \(| \sum ( A_i ) − L|^P\) ,求最小代价的划 ...
- 2018.10.14 NOIP训练 猜数游戏(决策单调性优化dp)
传送门 一道神奇的dp题. 这题的决策单调性优化跟普通的不同. 首先发现这道题只跟r−lr-lr−l有关. 然后定义状态f[i][j]f[i][j]f[i][j]表示猜范围为[L,L+i−1][L,L ...
- [NOI2009]诗人小G 决策单调性优化DP
第一次写这种二分来优化决策单调性的问题.... 调了好久,,,各种细节问题 显然有DP方程: $f[i]=min(f[j] + qpow(abs(sum[i] - sum[j] - L - 1))); ...
随机推荐
- 《A_Pancers团队》———团队项目原型设计与开发
一.实验目的与要求 (1)掌握软件原型开发技术: (2)学习使用软件原型开发工具:本实验中使用墨刀 二.实验内容与步骤 任务1:针对实验六团队项目选题,采用适当的原型开发工具设计团队项目原型: 任务2 ...
- Java的八种基本类型:(按字节来分)
Java的八种基本类型:(按字节来分) boolean 布尔型 1个字节 8bit(8位) byte 字节类型 1个字节 char 字符类型 2个字节 short ...
- cocos2dx 3.13 simulator的问题
下载新的cocos2dx 3.13,想使用simulator来运行lua项目,结果发现使用vs2013编译不通过. 1. 9>main.cpp(5): error C2146: 语法错误: 缺少 ...
- Redis之有序集合命令
Redis 有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过 ...
- [Java学习] Java虚拟机(JVM)以及跨平台原理
相信大家已经了解到Java具有跨平台的特性,可以“一次编译,到处运行”,在Windows下编写的程序,无需任何修改就可以在Linux下运行,这是C和C++很难做到的. 那么,跨平台是怎样实现的呢?这就 ...
- Imbalance Value of a Tree CodeForces - 915F
链接 大意: 给定树, 求树上所有链上最大值最小值之差 817D的树上版本, 用并查集维护即可. 817D由于是链的情况并查集不必压缩路径即可达到均摊$O(n)$, 该题必须压缩, 复杂度$O(nlo ...
- python 使用yield进行数据的流式处理
demo:从文件中取包含字符“a”的5行数据做一次批处理!!! # coding: utf-8 import time def cat(f): for line in f: yield line de ...
- elasticsearch 路由文档到分片
路由文档到分片 当你索引一个文档,它被存储在单独一个主分片上.Elasticsearch是如何知道文档属于哪个分片的呢?当你创建一个新文档,它是如何知道是应该存储在分片1还是分片2上的呢? 进程不能是 ...
- 如何用Curl 来post xml 数据
因为登陆服务升级,密码策略变更,以前的测试脚本中的用户密码已经不能登陆,试图通过API直接更改密码,一种是直接update,一种是change,使用curl的时候均未成功. 最后索性重新用curl命令 ...
- operator diag-up setting