话说BZOJ 是不是死了啊

(已经没有传送门了)

设 $f[i][j]$ 表示走到第 $j$ 个位置确定了 $i$ 个存档点时的最小代价,并强制第 $j$ 个位置有一个存档点

那么设 $cst[i][j]$ 表示存档点在 $i$ ,走到位置 $j$ 的代价, $f$ 有转移:

$f[i][j]=f[i-1][k]+cst[k][j]$

考虑 $cst[i][j]$ 如何计算,对每个起点 $i$ 求出 $i$ 指向的错误节点 $v$ 重新走回 $i$ 的期望步数 $dis[v]$,这个可以简单树形 $dp$ 得到

那么设 $val=\sum_{v \in son(j-1)} (cst[i][j-1]+1+dis[v])$ ,那么有 $cst[i][j]=cst[i][j-1]+1+val$

这里 $val$ 意义显然为从 $j-1$ 走到 $j$ 的期望代价,因为从 $j-1$ 到各个后继的概率一样,所以期望就是把每个后继各走一遍

加上 $cst[i][j-1]+1$ 显然是因为存档点在 $i$ ,要走到 $j-1$ 的后面一个儿子代价就是 $cst[i][j-1]+1$

然后这样就可以 $n^3$ 跑 $dp$ 了,考虑如何优化

把 $cst$ 的表打出来发现 $cst[i][j]$ 比 $cst[i][j-1]$ 的值大很多,发现 $cst$ 增长很快,显然超过一次函数

那么对于 $a<b<c<d$ ,就有 $cst[a][c]+cst[b][d]<=cst[a][d]+cst[b][c]$,即满足四边形不等式

所以对于 $f[i][j]$ 的最优转移点 $k$ ,$f[i][j+1]$ 的最优转移点一定不小于 $k$(不然我们直接从 $f[i-1][k]$ 转移会更优,写写式子就知道了)

然后用决策单调性分治优化即可

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
typedef double db;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=;
const db INF=1e99;
int T,n,m,p;
vector <int> V[N];
db f[N][N],cst[N][N],dis[N];
void dfs(int x,int fa)
{
int sz=V[x].size();
if(sz==) { dis[x]=; return; }
dis[x]=;
for(int i=;i<sz;i++)
{
int &v=V[x][i]; if(v==fa) continue;
dfs(v,x); dis[x]+=dis[v]+;
}
dis[x]/=sz-;
}
void solve(int i,int l,int r,int ql,int qr)
{
int mid=l+r>>,pos=ql,R=min(qr,mid-); f[i][mid]=INF;
for(int k=ql;k<=R;k++)
{
db val=f[i-][k]+cst[k][mid];
if(val<f[i][mid]) f[i][mid]=val,pos=k;
}
if(l<mid) solve(i,l,mid-,ql,pos);
if(mid<r) solve(i,mid+,r,pos,qr);
}
int main()
{
T=read();
while(T--)
{
n=read(),m=read(),p=read();
for(int i=;i<=m-n;i++)
{
int a=read(),b=read();
V[a].push_back(b); V[b].push_back(a);
}
for(int i=;i<=n;i++)
for(auto A: V[i]) dfs(A,i);
for(int i=;i<=n;i++)
{
cst[i][i]=;
for(int j=i+;j<=n;j++)
{
cst[i][j]=cst[i][j-]+;
for(auto A: V[j-])
cst[i][j]+=cst[i][j-]+ + dis[A];
}
}
f[][]=; for(int i=;i<=n;i++) f[][i]=INF;
for(int i=;i<=p;i++)
solve(i,,n,,n);
printf("%.4lf\n",f[p][n]);
for(int i=;i<=m;i++) V[i].clear();
}
return ;
}

BZOJ 4899 记忆的轮廓的更多相关文章

  1. bzoj 4899 记忆的轮廓 题解(概率dp+决策单调性优化)

    题目背景 四次死亡轮回后,昴终于到达了贤者之塔,当代贤者夏乌拉一见到昴就上前抱住了昴“师傅!你终于回来了!你有着和师傅一样的魔女的余香,肯定是师傅”.众所周知,大贤者是嫉妒魔女沙提拉的老公,400年前 ...

  2. [BZOJ4899]:记忆的轮廓(概率DP)

    题目传送门 题目描述: 通往贤者之塔的路上,有许多的危机. 我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增, 在[1,n]中,一共有n个节点.我 ...

  3. [bzoj4899]记忆的轮廓 题解(毒瘤概率dp)

    题目背景 四次死亡轮回后,昴终于到达了贤者之塔,当代贤者夏乌拉一见到昴就上前抱住了昴“师傅!你终于回来了!你有着和师傅一样的魔女的余香,肯定是师傅”.众所周知,大贤者是嫉妒魔女沙提拉的老公,400年前 ...

  4. Bzoj4899 记忆的轮廓

    B. 记忆的轮廓 题目描述 通往贤者之塔的路上,有许多的危机.我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增,在[1,n]中,一共有n个节点.我 ...

  5. 记忆的轮廓 期望 四边形不等式dp|题解

    记忆的轮廓 题目描述 通往贤者之塔的路上,有许多的危机.我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增,在[1,n]中,一共有n个节点.我们把编 ...

  6. BZOJ4899 记忆的轮廓(概率期望+动态规划+决策单调性)

    容易发现跟树没什么关系,可以预处理出每个点若走向分叉点期望走多少步才能回到上个存档点,就变为链上问题了.考虑dp,显然有f[i][j]表示在i~n中设置了j个存档点,其中i设置存档点的最优期望步数.转 ...

  7. BZOJ4899: 记忆的轮廓【概率期望DP】【决策单调性优化DP】

    Description 通往贤者之塔的路上,有许多的危机. 我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增, 在[1,n]中,一共有n个节点.我 ...

  8. NOIP模拟 1

    NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. #   用  户  名   ...

  9. 决策单调性优化dp 专题练习

    决策单调性优化dp 专题练习 优化方法总结 一.斜率优化 对于形如 \(dp[i]=dp[j]+(i-j)*(i-j)\)类型的转移方程,维护一个上凸包或者下凸包,找到切点快速求解 技法: 1.单调队 ...

随机推荐

  1. 【面试】ArrayList 和 HaseMap 的区别和应用场景

    ArrayLiat: ArrayList array = new ArrayList(); array.add("张三"); array.add("李四"); ...

  2. Leetcode题目226.翻转二叉树(简单)

    题目描述: 翻转一颗二叉树 示例: 输入: 4 / \ 2 7 / \ / \ 1 3 6 9 输出: 4 / \ 7 2 / \ / \ 9 6 3 1 思路分析: 1)递归,不断交换左右子树,直到 ...

  3. leetcode题目142.环形链表Ⅱ(中等)

    题目描述: 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 p ...

  4. JS基础_垃圾回收(GC)

    垃圾回收(GC) 程序运行过程中也会产生垃圾,这些垃圾积攒过多以后,会导致程序运行的速度过慢,所以我门需要一个垃圾回收的机制,来处理程序运行过程中产生的垃圾 当一个对象没有任何的变量或属性对它进行引用 ...

  5. 微信小程序 图片裁剪

    微信小程序 图片裁剪 分享一个微信小程序图片裁剪插件,很好用,支持旋转 文档:https://github.com/wyh19931106/image-cropper 1.json文件中添加image ...

  6. VS2008 Qt Designer 中自定义信号槽

    一.Qt Designer自定义槽函数 发现:在VS2008 +Qt4.7  中打开ui文件,所用的英文QT Designer工具,没有转到槽函数的功能,不如QtCreator自带的QtDesigne ...

  7. 关于本电脑qt5.11+vs2017+opencv3.4的配置问题

    本人想用qt5.11+vs2017+opencv3.4开发程序,配置了很久才成功,现在把配置后的环境变量记录一下,以供自己以后参考,同时也供大家参考. qt5.11+vs2017+opencv3.4的 ...

  8. GitHub代码下载和同步

    1.下载git客户端https://git-scm.com/ssh-keygen -C "your@email.address" -t rsa 2. 把下面文件的内容复制到 htt ...

  9. java错误与异常

    java异常处理机制 异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常, 让程序尽最大可能恢复正常并继续执行,且保持代码的清晰.Java中的异常可以是函数中的语句执 ...

  10. es6 单例

    class Singleton { constructor() { this.conn = this.connect(); } static getInstance() { if (!Singleto ...