容易发现跟树没什么关系,可以预处理出每个点若走向分叉点期望走多少步才能回到上个存档点,就变为链上问题了。考虑dp,显然有f[i][j]表示在i~n中设置了j个存档点,其中i设置存档点的最优期望步数。转移枚举下一个存档点设在哪,则有f[i][j]=min(f[k][j-1]+d[i][k]),其中d[i][k]为从i号点存档点走到k号存档点其间没有别的存档点的期望步数。对d数组可以把一堆方程列出来手动加减消元得到式子,n2就可以求出。这样复杂度O(Tn3)。于是直接暴力就在darkbzoj上水过了。或者加一些乱七八糟的剪枝就能跑得飞快。然后有感性理解比较显然的一点是这个东西有决策单调性,于是就能做到O(Tn2logn)。证明估计得列一堆式子不太敢证了。然而由于d数组已经大到爆了精度,需要一些乱七八糟的处理,本来还以为是决策单调性写挂了调了半天一点卵用都没有。尽管这样还是没在bzoj上过掉,不知道bzoj有什么奇怪的精度问题。被恶心死了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 710
#define inf 1000000000
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int T,n,m,k,p[N<<],L[N],R[N],id[N],top,t;
double v[N<<],d[N][N],f[N][N],son[N<<];
struct data{int to,nxt;
}edge[N<<];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dfs(int k)
{
for (int i=p[k];i;i=edge[i].nxt)
{
son[k]++;
dfs(edge[i].to);
v[k]+=v[edge[i].to]+;
}
if (son[k]) v[k]/=son[k];
son[k]++;
}
double calc(int i,int x,int y){return f[i-][y]+d[x][y];}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4899.in","r",stdin);
freopen("bzoj4899.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
T=read();
while (T--)
{
n=read(),m=read(),k=read();
memset(p,,sizeof(p));t=;
memset(son,,sizeof(son));
memset(v,,sizeof(v));
for (int i=;i<=m-n;i++)
{
int x=read(),y=read();
addedge(x,y);
}
for (int i=;i<=n;i++) dfs(i),v[i]++;
for (int i=;i<n;i++)
{
double t=;
for (int j=i;j<n;j++)
{
d[i][j+]=d[i][j]+t/son[j]+t*(son[j]-)/son[j]*v[j];
t/=son[j];
}
t=;double s=;
for (int j=i;j<n;j++)
{
s-=t*(son[j]-)/son[j];
d[i][j+]/=s;
t/=son[j];
}
}
for (int i=;i<n;i++) f[][i]=inf;
for (int i=;i<=n;i++)
for (int j=i+;j<=n;j++)
if (d[i][j]>inf) d[i][j]=1ll*inf*(j+);
for (int i=;i<=k;i++)
{
top=;id[]=n;L[]=,R[]=n-;
for (int j=n-;j>=;j--)
{
int l=,r=top,x=;
while (l<=r)
{
int mid=l+r>>;
if (L[mid]<=j&&R[mid]>=j) {x=mid;break;}
else if (L[mid]>j) l=mid+;
else r=mid-;
}
f[i][j]=calc(i,j,id[x]);
while (top&&R[top]<j&&calc(i,R[top],j)<calc(i,R[top],id[top])) top--;
l=L[top],r=min(j,R[top])-,x=L[top]-;
/*for (int p=r;p>=l;p--)
if (calc(i,p,j)<calc(i,p,id[top])) {x=p;break;}*/
while (l<=r)
{
int mid=l+r>>;
if (calc(i,mid,j)<calc(i,mid,id[top])) x=mid,l=mid+;
else r=mid-;
}
L[top]=x+;
if (x) top++,id[top]=j,L[top]=,R[top]=x;
}
}
/*for (int i=2;i<=k;i++)
for (int j=n-1;j>=1;j--)
{
f[i][j]=inf;
for (int x=j+1;x<=min(j+7+n/k,n);x++)
f[i][j]=min(f[i][j],calc(i,j,x));
}*/
printf("%.4f\n",f[k][]);
}
return ;
}

BZOJ4899 记忆的轮廓(概率期望+动态规划+决策单调性)的更多相关文章

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

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

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

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

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

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

  4. Bzoj4899 记忆的轮廓

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

  5. BZOJ1563 NOI2009诗人小G(动态规划+决策单调性)

    设f[i]为前i行的最小不协调度,转移枚举这一行从哪开始,显然有f[i]=min{f[j]+abs(s[i]-s[j]+i-j-1-m)p}.大胆猜想有决策单调性就好了.证明看起来很麻烦,从略.注意需 ...

  6. 【题解】亚瑟王 HNOI 2015 BZOJ 4008 概率 期望 动态规划

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4008 一道不简单的概率和期望dp题 根据期望的线性性质,容易想到,可以算出每张卡的期望伤害, ...

  7. BZOJ5305 HAOI2018苹果树(概率期望+动态规划)

    每种父亲编号小于儿子编号的有标号二叉树的出现概率是相同的,问题相当于求所有n个点的此种树的所有结点两两距离之和. 设f[n]为答案,g[n]为所有此种树所有结点的深度之和,h[n]为此种树的个数. 枚 ...

  8. BZOJ4832 抵制克苏恩(概率期望+动态规划)

    注意到A+B+C很小,容易想到设f[i][A][B][C]为第i次攻击后有A个血量为1.B个血量为2.C个血量为3的期望伤害,倒推暴力转移即可. #include<iostream> #i ...

  9. UOJ#196. 【ZJOI2016】线段树 概率期望,动态规划

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ196.html 题解 先离散化,设离散化后的值域为 $[0,m]$ . 首先把问题转化一下,变成:对于每一个位置 $i$ ...

随机推荐

  1. ELKStack入门篇(二)之Nginx、Tomcat、Java日志收集以及TCP收集日志使用

    1.收集Nginx的json格式日志 1.1.Nginx安装 [root@linux-node1 ~]# yum install nginx -y [root@linux-node1 ~]# vim ...

  2. django中的路由控制详解

    一 Django中路由的作用 二 简单的路由配置 三 有名分组 四 路由分发 五 反向解析 六 名称空间 七 django2.0版的path 一 Django中路由的作用 URL配置(URLconf) ...

  3. XAF-如何改变列表点击时的默认行为

    在 Windows 窗体应用程序中,按下回车或双击列表会打开默认的详细视图. 在 ASP.NET Web 应用程序中,单击对象时执行此操作. 这一行为是由 ListViewProcessCurrent ...

  4. 图 -数据结构(C语言实现)

    读数据结构与算法分析 坑!待填! 若干定义 一个图G = (V , E)由顶点集V和边集E组成,每条边就是一个点对 如果点对是有序的,那么就叫做有向图 边可能还具有第三种成分,权值 无向图种从每个顶点 ...

  5. Centos7下安装Oracle11g r2

    我的centos7是在virtualbox下安装的,安装Oracle安装了好久好久,最开始的时候在网上找的两个文章,按照步骤装,有一篇写着装的时候有灰色的竖线,直接按space键或者鼠标右键close ...

  6. 华为笔试——C++转换字符串问题

    题目:转换字符串 题目介绍: 将输入字符串中下标为偶数的字符连成一个新的字符串输出,需要注意两点: 1. 如果输入字符串的长度超过20,则转换失败,返回“ERROR!”字符串: 2. 输入字符串只能由 ...

  7. 转:为什么说招到合适的人比融到钱更加重要 - Hiring Great Talent is More Important Than Fund Raising

    我在猎头行业工作了 20 多年,一直在帮助创业公司招聘优秀的人才.我服务过的客户既有 VC 投资的初创企业,也有即将 IPO 的公司.我和 200 多个 VC 合作过,也见过 300 多个客户失败的案 ...

  8. Beautiful Year(拆分四位数)

    Description It seems like the year of 2013 came only yesterday. Do you know a curious fact? The year ...

  9. 第七次作业PSP

    psp 进度条 代码累积折线图 博文累积折线图 psp饼状图

  10. 软工1816·Alpha冲刺(10/10)

    团队信息 队名:爸爸饿了 组长博客:here 作业博客:here 组员情况 组员1(组长):王彬 过去两天完成了哪些任务 协助完成前端各个页面的整合 协助解决前端操作逻辑存在的问题 完成前端的美化,使 ...