http://www.lydsy.com/JudgeOnline/problem.php?id=1065

https://vijos.org/p/1826

好难的题啊TWT

∈我这辈子也想不出来系列~

题解详见2009年的论文徐源盛《对一类动态规划问题的研究》。


这道题我第一眼一脸懵逼。。。

然后持续懵逼。。。

最后看论文里的题解



我再来重复一下(论文绝对比我讲得详细QAQ)

首先\(R(i)=C_i+k\sum_\limits{j=1}^wR(p_j)\)

如果是单纯的一棵树,那么从孩子传到父亲非常方便。但是根节点1处会有向其他点的边形成环,这样怎么统计?

根据题解:把所有点的递推式写出来,然后迭代一下,把环上的点的R值全用1的R值和其他点的C值表示,然后把R(1)提出来得到:$$R(1)=\frac{\sum_\limits{j=1}nC_i*k{d(i,1)}}{1-k^{len}}$$

这样环长len确定时,只要分子尽可能大就可以了,这是第一步。

光第一步我就gg了QwQ



又因为\(k<1\),所以如果一个点的C值要对R(1)贡献尽可能的大,那么如果修改这个点,一定直接把这个点连向1,否则肯定不是最优的。

那么类似IOI2015河流那道题,子节点的状态的改变会对它的祖先的状态值有影响,需要新增状态来记录未来可能发生的情况。

设用\(f(i,j,d)\)表示以点i为根的树中,修改j次,且点i到1的距离为d的最大值。

为了方便转移令\(g(i,j,d)=max\{f(i,j,d+1),f(i,j,1)\}\)

\(f(i,j,d)=max\{g(s_1,j_1,d)+g(s_2,j_2,d)+\dots +g(s_t,j_t,d)\}+c(i)*k^d\)

\(s_1,s_2\dots s_t\)为i的t个儿子。

如果i节点不修改后继,\(j_1+j_2+\dots +j_t=j\)

如果i节点修改后继为1,\(j_1+j_2+\dots +j_t=j-1\),且\(d=1\)

为了避免转左儿子右兄弟,f的转移可以用FF数组来加速,\(FF(i,j)\)表示前i个孩子分配j次修改能得到的最大贡献。

套在最外面的一步是枚举环的长度。因为最终树的环上的点一定是原先的树中环上的点(环上的点是哪些不重要,重要的是环的长度,用原先环上的点可以节省修改次数给其他节点用)。

扫出以1为首节点的环(如图1,2,3,4,5,6)



然后枚举最终树上环的长度len,如图蓝线描出了最终的环,此时len为4



4的后继边指向了1。

然后对1到4所有节点为根的外向树进行dp,注意此时5,6及其外向树也应算作1的外向树。

如图,此时最优答案为\(f(1,j_1,0)+f(2,j_2,3)+f(3,j_3,2)+f(4,j_4,1)\)

其中\(\sum j=m-1\),(如果len为原环长,\(\sum j=m\))

再用dp算一下当前环长下的正确答案就可以啦。

时间复杂度\(O(n^3m^2)\),虽然看起来不可过,不过可以过的~

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 63; struct node {int nxt, to;} E[N]; int n, m, T[N], point[N], cnt, cir[N], ctot = 0, a[N], atot, deep[N];
double k, f[N][N][N], g[N][N][N], FF[N][N], C[N], ipow[N];
bool vis[N]; void ins(int u, int v) {E[++cnt] = (node) {point[u], v}; point[u] = cnt;} void pre_dfs(int x) {
for (int i = point[x]; i; i = E[i].nxt)
if (!vis[E[i].to])
deep[E[i].to] = deep[x] + 1, pre_dfs(E[i].to);
} void dp(int x) {
for (int i = point[x]; i; i = E[i].nxt)
if (!vis[E[i].to])
dp(E[i].to); atot = 0;
for (int i = point[x]; i; i = E[i].nxt)
if (!vis[E[i].to]) a[++atot] = E[i].to; for (int d = deep[x]; d >= 1; --d) {
for (int i = 1; i <= atot; ++i)
for (int l = 0; l <= m; ++l)
FF[i][l] = 0;
for (int i = 1; i <= atot; ++i)
for (int l = 0; l <= m; ++l)
for (int nowl = 0; nowl <= l; ++nowl)
FF[i][l] = max(FF[i][l], FF[i - 1][l - nowl] + g[a[i]][nowl][d]);
for (int j = 0; j <= m; ++j)
f[x][j][d] = FF[atot][j] + C[x] * ipow[d];
} if (x == 1) {
for (int i = 1; i <= atot; ++i)
for (int l = 0; l <= m; ++l)
FF[i][l] = 0;
for (int i = 1; i <= atot; ++i)
for (int l = 0; l <= m; ++l)
for (int nowl = 0; nowl <= l; ++nowl)
FF[i][l] = max(FF[i][l], FF[i - 1][l - nowl] + g[a[i]][nowl][0]);
for (int j = 0; j <= m; ++j)
f[x][j][0] = FF[atot][j] + C[x];
} else {
for (int j = 1; j <= m; ++j)
f[x][j][1] = max(f[x][j][1], FF[atot][j - 1] + C[x] * k);
} for (int d = deep[x] - 1; d >= 0; --d) {
g[x][0][d] = f[x][0][d + 1];
for (int j = 1; j <= m; ++j)
g[x][j][d] = max(f[x][j][d + 1], f[x][j - 1][1]);
}
} int main() {
scanf("%d%d%lf", &n, &m, &k);
for (int i = 1; i <= n; ++i) {
scanf("%d", T + i);
ins(T[i], i);
}
for (int i = 1; i <= n; ++i)
scanf("%lf", C + i);
ipow[0] = 1;
for (int i = 1; i <= n; ++i)
ipow[i] = ipow[i - 1] * k; int tmp = T[1]; cir[++ctot] = 1;
while (tmp != 1) {
cir[++ctot] = tmp;
tmp = T[tmp];
} double ans = 0, ret;
vis[1] = true;
for (int len = 2; len <= ctot; ++len) {
vis[cir[len]] = true;
pre_dfs(1);
cnt = len;
for (int i = 2; i <= len; ++i)
deep[cir[i]] = --cnt, pre_dfs(cir[i]);
memset(f, 0, sizeof(f));
memset(g, 0, sizeof(g)); for (int i = 1; i <= len; ++i)
dp(cir[i]); cnt = len;
memset(FF, 0, sizeof(FF));
for (int i = 0; i <= m; ++i)
FF[1][i] = f[1][i][0];
for (int i = 2; i <= len; ++i) {
--cnt;
for (int j = 0; j <= m; ++j)
for (int nowl = 0; nowl <= j; ++nowl)
FF[i][j] = max(FF[i][j], FF[i - 1][j - nowl] + f[cir[i]][nowl][cnt]);
}
if (len < ctot) ans = max(ans, FF[len][m - 1] / (1.0 - ipow[len]));
else ans = max(ans, FF[len][m] / (1.0 - ipow[len]));
// printf("%.2lf\n", f[1][1][0]);
} printf("%.2lf\n", ans); // for (int i = 1; i <= ctot; ++i)
// printf("%d\n", cir[i]); return 0;
}

【BZOJ 1065】【Vijos 1826】【NOI 2008】奥运物流的更多相关文章

  1. bzoj 1065: [NOI2008] 奥运物流

    1065: [NOI2008] 奥运物流 Description 2008北京奥运会即将开幕,举国上下都在为这一盛事做好准备.为了高效率.成功地举办奥运会,对物流系统 进行规划是必不可少的.物流系统由 ...

  2. 从多种角度看[BZOJ 1061] [NOI 2008]志愿者招募(费用流)

    从多种角度看[BZOJ 1061] [NOI 2008]志愿者招募(费用流) 题面 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运 ...

  3. 【BZOJ1065】【NOI2008】奥运物流(动态规划)

    [BZOJ1065][NOI2008]奥运物流(动态规划) 题面 BZOJ 洛谷 题解 先不考虑环的情况,于是变成了一棵树. 这样子我们答案的贡献是\(\sum_{i=1}^nC_i\times k^ ...

  4. [补档][NOI 2008]假面舞会

    [NOI 2008]假面舞会 题目 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一个自己喜欢的面具. 每个面具都有一 ...

  5. [LOJ 2720][BZOJ 5417][UOJ 395][NOI 2018]你的名字

    [LOJ 2720][BZOJ 5417][UOJ 395][NOI 2018]你的名字 题意 给定一个大串 \(S\) 以及 \(q\) 次询问, 每次询问给定一个串 \(T\) 和区间 \([l, ...

  6. 【洛谷】P4202 [NOI2008]奥运物流

    [洛谷]P4202 [NOI2008]奥运物流 感觉有点降智 首先设环长为\(len\),很容易推导出 \[ R(1) = \frac{\sum_{i = 1}^{N} C_{i} k^{dep[i] ...

  7. 题解 Sue的小球/名次排序问题/方块消除/奥运物流

    Sue的小球 名次排序问题 方块消除 奥运物流 Sue的小球 题目大意 有 \(n\) 个小球在下落,初始位置 \((x_i,y_i)\),下落速度为 \(v_i\).你初始位置在 \(x_0\),速 ...

  8. NOI 2008 志愿者招募

    NOI 2008 志愿者招募 考虑用 $ p_i $ 表示第 $ i $ 天实际招收的人数,我们假设我们有三种志愿者,分别是 $ 1\to 2,1 \to 3 , 2\to 3 $ ,我们招手的人数分 ...

  9. 【BZOJ 1061】【Vijos 1825】【NOI 2008】志愿者招募

    http://www.lydsy.com/JudgeOnline/problem.php?id=1061 https://vijos.org/p/1825 直接上姜爷论文... #include< ...

随机推荐

  1. UITextField的代理方法:textField:shouldChangeCharactersInRange:replacementString

    原文链接:http://www.cnblogs.com/zhanggui/p/6101813.html 这个我在开发的过程中用到的次数最多,因此这里就简单对其进行分析.先看看Command+点击 弹出 ...

  2. 使用AIDL调用远程服务设置系统时间

    在实际工作中,经常遇到客户需要用代码设置系统时间的需求,但是Android非系统应用是无法设置系统时间的.于是,我设计了一个使用系统签名的时间设置服务,客户通过bind调用服务里的方法就能达到设置时间 ...

  3. C++实现Ping

    这是一个老话题了,但是我刚学会... 我们的目的是实现这么个东西: 之所以用红框框一下是因为,从baidu.com到123.125.114.144的过程是DNS解析,我们暂时先实现ping的部分. 基 ...

  4. IE10 和 Chrome50 对日期 new Date() 支持的区别

    IE10 和 Chrome50 对日期 new Date() 支持的区别: new Date('2016-06-18'); // IE10 不通过.Chrome 通过 new Date('2016/0 ...

  5. 敏捷开发与jira之流程

    敏捷流程在Jira中的运用

  6. dropzonejs中文翻译手册 DropzoneJS是一个提供文件拖拽上传并且提供图片预览的开源类库.

    http://wxb.github.io/dropzonejs.com.zh-CN/dropzonezh-CN/ 由于项目需要,完成一个web的图片拖拽上传,也就顺便学习和了解了一下前端的比较新的技术 ...

  7. Linux 平台MySQL启动关闭方式总结

    MySQL的启动方法有很多种,下面对比.总结这几种方法的一些差异和特性,下面实验的版本为MySQL 5.6.如有疏漏或不足,敬请指点一二.   1:使用mysqld启动.关闭MySQL服务 mysql ...

  8. Vmware扩展磁盘如何不需重启系统

    在虚拟机Vmware中我们有时候需要添加新的虚拟磁盘或给已有虚拟磁盘扩容(expand),在新增磁盘或磁盘扩容后,Linux系统并不能马上识别到.也就是说你看不到磁盘空间变化(使用fdisk -l查看 ...

  9. .NET应用程序调试—原理、工具、方法

    阅读目录: 1.背景介绍 2.基本原理(Windows调试工具箱..NET调试扩展SOS.DLL.SOSEX.DLL) 2.1.Windows调试工具箱 2.2..NET调试扩展包,SOS.DLL.S ...

  10. URLEncoder.encode 和 URLDecoder.decode 处理url的特殊参数

    在使用 url 的 queryString 传递参数时,因为参数的值,被DES加密了,而加密得到的是 Base64的编码字符串,类似于: za4T8MHB/6mhmYgXB7IntyyOUL7Cl++ ...