- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
《GEMS》解题报告
珠宝
给一棵n个结点的树,给每个点安排一个正整数编号,使得相邻点具有不同的编号,编号的总和尽量小。
输入
第一行:n(n=50,000)
以下n-1行,每行两个数u,v(1=u,v=n),表示u 和v有一条边
输出
仅一行,为最小编号和
样例输入
8
1 2
1 3
1 4
1 5
5 6
5 7
5 8
样例输出
11
分析:
看完题目,很自然地联想到树型DP,而且也不难得到状态表示方法。先根据输入的数据构造出一棵树,然后从树的叶子结点往上倒推。设F[I,J]表示以I为根的子树在I的编号为J时,可以得到的最小编号和。
状态转移方程为:F[I,J] = Min{∑F[I1, J1]} + J
其中I1表示I的一个子结点编号,J1为不同于J的一个自然数。
很显然,在最优方案中,所有解的编号都是不可能超过N的。因此不难推出算法的时间复杂度为O(N^3),空间复杂度为O(N^2)。这对于本题的规模来说,是无法承受的。
分析一下几个比较小的数据,会发现在最优方案中,最大的编号全部都没有达到N,不妨设其为M。而且凭感觉来看,M比N要小很多。很自然地,我们会考虑计算出这个比N小的M,然后DP的时候只要对每个点考虑编号为1到M的状态即可。这样时间复杂度就降为O(NM^2),空间复杂度降为O(NM)。但是M究竟怎么得到呢?我们发现这是很难计算的,而且也不太好估算出一个界(至少我没有想到好的方法)。事实上可以采取一种比较无奈的方法。因为N最大为50000,时限为1S,所以要想算法在理论上的最坏情况下不超时,M取30左右比较保险,实践证明,M取30足以通过所有测试数据了。
似乎通过上面的分析本题已经解决得差不多了,但M毕竟是“贪”出来的,正确性不能得到理论上的证明,我们不妨从算法优化的角度来考虑这个问题。还是回到最初的DP算法。仔细推敲一下就会发现,F[I,1 .. M]这M个状态中,能够在以后的状态转移中真正利用到的只有两个,它们是这M个状态中值最小的两个。因此,可以将算法做一下改进,设F[I,1],F[I,2],NUM[I,1],NUM[I,2]分别表示F[I,1..M]中值最小的两个,以及此时点I的编号。状态转移方程只要在原来的基础上做下改进即可:
先求出F[I,1 .. M],再保留其中最小的两个。为了描述方便,用辅助数组F1[1 .. M]表示F[I,1 .. M],那么有
F1[J] = ∑F[I1,J1] + J
其中I1表示I的子结点。若NUM[I1,1] = J,则J1 = 2,否则J1 = 1
此时时间复杂度降为O(N^2),空间复杂度降为O(N)。时间方面仍然不理想。再分析一下,可以发现,若找到一个最小的J满足J + ∑F[I1,1] = F[I,2],那么F[I,J..M]显然都是不小于F[I,2]的,所以此时可以停止计算后面的状态了。类似的,在求某一个F1[J]的过程中,如果当前累加变量的值不小于F[I,2],也可以停止计算F1[J]啦。
这两个剪枝加上去后,该算法可以瞬间通过所有数据。而且分析一下就会发现,该算法的时间复杂度大约为O(KN),K是一个相对于N来说比较小的系数。
参考程序:
const
maxn = 50000;
type
tg = array[1 .. maxn] of longint;
var g : array[1 .. maxn] of ^tg;
d, fa, son : array[1 .. maxn] of longint;
f, num : array[1 .. maxn, 1 .. 2] of longint;
n, m, s, min : longint;
procedure init;
var i, x, y : longint;
begin
readln(n);
for i :=1 to n - 1 do begin
readln(x, y); inc(d[x]); inc(d[y]);
end;
for i :=1 to n do begin
getmem(g[i], sizeof(longint) * d[i]);
d[i] :=0;
end;
readln(n);
for i :=1 to n - 1 do begin
readln(x, y);
inc(d[x]); g[x].[d[x]] :=y;
inc(d[y]); g[y].[d[y]]
您可能关注的文档
最近下载
- 福建省漳州第一中学(西湖校区)2024-2025学年高一下学期第一次阶段考试生物学试题(含答案).pdf VIP
- 心血管-肾脏-代谢综合征患者的综合管理中国专家共识(2025)解读PPT课件.pptx VIP
- YD∕T 5066-2017 -光缆线路自动监测系统工程设计规范.pdf VIP
- (高清版)B-T 17671-2021 水泥胶砂强度检验方法(ISO法).pdf VIP
- 骨科手术切口感染的预防与控制.pptx
- 人教版初一上册《化学》模拟考试卷及答案【可打印】.docx VIP
- 《宴席设计实务》(肖炜)教案 第6课 为西式宴席设计酒水.docx VIP
- 塔吊驾驶员安全培训试题及答案.doc VIP
- ASME BPVC-VII-2017 锅炉及压力容器规范 第七卷:动力锅炉维护推荐指南 国外国际标准.pdf VIP
- GB_T 17671-2021水泥胶砂强度检验方法(ISO法).docx VIP
文档评论(0)