题目描述可能稍有偏差,但实质上是一样的。

看下面

题目大意

题面这么长,先说说题意吧。

就是有一个操作系统,他的存储方式是树形的。其中分为文件和目录(文件夹)每一个子目录下只能存储 $K$ 个文件或目录。并且有 $K$ 个指针分别指向这 $K$ 个文件或文件夹。每一个指针都有一个访问时间 $P$。

然后每一个文件或目录都有一个访问时间,文件和目录的访问时间计算方式不相同

  • 文件:访问其所有上级目录(就是这个文件访问路径上的文件夹)的访问时间加上这个文件的指针的访问时间。
  • 文件夹:它的各级子目录下文件的个数 $\times $ 它的指针的访问时间。通俗一点就是它的子树上的文件的个数为 $x$,它的指针访问时间是 $y$ 那么它的访问时间就是 $x\times y$。这里要说一下题面描述出了锅,最起码我现在看是这样的。

现在你需要计算出给出的 $N$ 个文件的最小访问时间总和。

解题思路

我看了Vijos上的题解表示并没有看懂,于是问问机房的dalao。dalao就是dalao。

这是一道树形DP。首先要明白一个贪心策略。在同一层子目录下,如果现在的剩余空间已经无法容纳剩下的文件那么我们必然是需要在开一个文件夹进行存储的。那这个文件夹开的位置的指针访问时间越小越好。因为如果它是一个文件夹的话,它对答案的影响会随着它的子目录中文件的数量增加而成倍增加。所以要尽量的小。这就是一个贪心的策略,显然在输入的时候是需要对指针的访问时间从小到大排序的。

接下来做树形dp。先看下代码,我们一段一段的讲。

int main() {
scanf("%d%d", &n, &k);
for(int i=; i<=k; i++)
scanf("%d", &p[i]);
sort(p+, p++k);
printf("%d", dp(n, , n-));
}

排序这一部分自然是不用多说了,上面已经说过了。

再来看dp函数

inline int dp(int x, int y, int l) {
if(x == ) {
f[x][y] = p[y];
return f[x][y];
}
if(y == k) {
f[x][y] = p[y] * x * x + dp(x, , x-);
return f[x][y];
}
int tmp = k-y+;
if(tmp * l < x)
return INF;
if(f[x][y]) return f[x][y];
tmp = (x-)/tmp + ;
for(int i=tmp; i<=l; i++) {
if(i == )
f[x][y] = p[y] + dp(x-, y+, x-);
else
f[x][y] = MIN(f[x][y], dp(x-i, y+, x-i-) + dp(i, , i-) + p[y] * i * i);
}
return f[x][y];
}

$x$ 表示还剩下多少个文件没有被安排。$y$ 表示现在用到的是第 $y$ 个指针。$f[x][y]$ 表示还剩 $x$ 个文件用第 $y$ 个指针的最小的访问时间。

显然如果 $x == 1$ 的话,就直接将现在这个指针的时间给它就好了。如果 $y==k$ 的话,说明 $k$ 个指针已经用到了最后一个那肯定是要建一个文件夹。

这里的 $p[y]*x*x$ 的含义呢,是将这个文件夹的访问时间计算出来并且它之后会产生 $x$ 次影响,将这 $x$ 次影响在这里直接计算出来。

$l$ 表示层数,是最多还能伸下去安排几层。$tmp$ 那个地方是一个小剪枝。如果剩余的内存还不够将这 $x$ 个文件安排好的话就直接反回 $inf$。

往后的状态转移,如果只剩下一个需要安排的话,那就直接安排上。否则的话就开一个文件夹,把除文件夹外的剩余空间进行分配,并且往下深入一层。

附上代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = , INF = ;
int n, k, p[], f[maxn][maxn];
inline int MIN(int x, int y) {
if(!x) return y;
else return min(x, y);
}
inline int dp(int x, int y, int l) {
if(x == ) {
f[x][y] = p[y];
return f[x][y];
}
if(y == k) {
f[x][y] = p[y] * x * x + dp(x, , x-);
return f[x][y];
}
int tmp = k-y+;
if(tmp * l < x)
return INF;
if(f[x][y]) return f[x][y];
tmp = (x-)/tmp + ;
for(int i=tmp; i<=l; i++) {
if(i == )
f[x][y] = p[y] + dp(x-, y+, x-);
else
f[x][y] = MIN(f[x][y], dp(x-i, y+, x-i-) + dp(i, , i-) + p[y] * i * i);
}
return f[x][y];
}
int main() {
scanf("%d%d", &n, &k);
for(int i=; i<=k; i++)
scanf("%d", &p[i]);
sort(p+, p++k);
printf("%d", dp(n, , n-));
}

「 Luogu P2230 」X 「 Vijos 1142 」 HXOS系统的更多相关文章

  1. 「Luogu P2468 [SDOI2010]粟粟的书架」

    这道题分为两个部分 Part1 前置芝士 前缀和(后缀和,二维前缀和):可以预处理一下数据. 二分查找:可以在较短的时间内找出答案. 具体做法 可以发现\(R,C\)不大,只有\(200\),于是可以 ...

  2. 「Luogu P3078 [USACO13MAR]扑克牌型Poker Hands」

    本题有\(O(N)\)的优秀做法,但是因为在考场上不一定能想到,就来分享一种\(O(N\log_2N)\)的做法.虽然有点慢,但是可以过. 前置芝士 线段树:提高组及以上必备内容,不会的同学可以学习一 ...

  3. 「Luogu P3820 小D的地下温泉」

    这道题的考点比较多. 前置芝士 BFS(DFS),这两种算法在这道题中并没有什么特别突出的地方,基本就是自己看心情写(本文以DFS为准,所以我心情是好是坏呢?) 连通块,可以将每一个温泉看作一个连通块 ...

  4. 「Luogu P2253 好一个一中腰鼓!」

    就这道题的理论难度来说绿题是有点低了,但是这道题的实际难度来看,顶多黄题,所以建议加强数据或出数据升级版. 前置芝士 线段树:具体可以看我的另一篇文章. 具体做法 暴力的方法想必都会,所以来讲一下正解 ...

  5. Git 执行 「fork 出来的仓库」和「最新版本的原仓库」内容同步更新

    当我们在 GitHub 上 fork 出一个仓库后,如果原仓库更新了,此时怎样才能保证我们 fork 出来的仓库和原仓库内容一致呢?我们一般关注的是仓库的 master(主干分支)的内容,通过以下步骤 ...

  6. FileUpload控件「批次上传 / 多档案同时上传」的范例--以「流水号」产生「变量名称」

    原文出處  http://www.dotblogs.com.tw/mis2000lab/archive/2013/08/19/multiple_fileupload_asp_net_20130819. ...

  7. Java的参数传递是「值传递」还是「引用传递」?

    关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题. 有人说Java中只有值传递,也有人说值传递和引用传递都是存在的,比较容易让人产生疑问. 关于值传递和引用传递其实需要分情况看待. ...

  8. Linux 小知识翻译 - 「Unix」和「兼容Unix的OS」

    经常有人会问「Linux和Unix有什么区别?」,「Linux就是Unix吗?」. 回答一般都是「Linux是仿照Unix而开发的OS」,「Linux和Unix相似但不是一种OS」之类的. 关于「Li ...

  9. Linux 小知识翻译 - 「Linux」和「发行版」之间的关系

    「Linux」本来指的仅仅是内核.5年之前大多都是这么认为的,但是最近不这么说了. 最近一般都说「Linux」是个 OS,这里的OS,不仅仅是内核,而是指电脑的整体环境(除了内核,还包括一些外围的软件 ...

随机推荐

  1. [noip模拟赛]跑跑步

    https://www.zybuluo.com/ysner/note/1298652 题面 小胡同学是个热爱运动的好孩子. 每天晚上,小胡都会去操场上跑步,学校的操场可以看成一个由\(n\)个格子排成 ...

  2. 8 种提升ASP.NET Web API性能的方法

    ASP.NET Web API 是非常棒的技术.编写 Web API 十分容易,以致于很多开发者没有在应用程序结构设计上花时间来获得很好的执行性能. 在本文中,我将介绍8项提高 ASP.NET Web ...

  3. E20170612-sl

     tampon n.     卫生棉塞; 止血棉塞;    sanitary  n. 公共厕所;  adj.     卫生的; 清洁的;    belonging n.     附属品,附件,属性; ...

  4. Python网咯爬虫 — Scrapy框架应用

    Scrapy框架       Scrapy是一个高级的爬虫框架,它不仅包括了爬虫的特征,还可以方便地将爬虫数据保存到CSV.Json等文件中.       Scrapy用途广泛,可以用于数据挖掘.监测 ...

  5. 分布式消息通信(ActiveMQ)

    分布式消息通信(ActiveMQ) 应用场景 异步通信 应用解耦 流量削峰 # ActiveMQ安装 下载 http://activemq.apache.org/ 压缩包上传到Linux系统 apac ...

  6. sql server 大数据处理

    对SQL Server数据表进行分区的过程分为三个步骤: 1)建立分区函数 2)建立分区方案 3)对表格进行分区 第一个步骤:建立分区函数 分区函数定义[u]how[/u],即你想要SQL Serve ...

  7. EditText(6)EditText的子类

      1.Known Direct Subclasses AppCompatEditText, AutoCompleteTextView, ExtractEditText, GuidedActionEd ...

  8. JavaScript 把函数作为参数进行传值

    JavaScript 响应式编程模式有点类似 WebForm 中的事件驱动模式(传相应的处理函数给委托,通过事件来触发来进行相关的处理),在 AngularJs 2.x 框架中,应用了 RxJS AP ...

  9. Silverlight环境配置

    今天对Silverlight安装环境进行了配置,本系统已经安装VS2010 和 Silverlight 5. 要开发Silverlight必须安装Developer Runtime 和 SDK , 且 ...

  10. (转)SqlServer2008开启客户端远程连接

    原文地址:http://wenku.baidu.com/link?url=MiiJG0SKUUAb3kzrrQtdx0zGIDpsGa7vcGlzqIDe7qcFx5NJ4UlVoPIswxZCHMo ...