codevs1746 贪吃的九头龙
【问题描述】
传说中的九头龙是一种特别贪吃的动物。虽然名字叫“九头龙”,但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头因衰老而自己脱落。
有一天,有 M 个脑袋的九头龙看到一棵长有 N 个果子的果树,喜出望外,恨不得一口把它全部吃掉。可是必须照顾到每个头,因此它需要把 N 个果子分成 M 组,每组至少有一个果子,让每个头吃一组。
这 M 个脑袋中有一个最大,称为“大头”,是众头之首, 它要吃掉恰好 K 个果子,而且 K 个果子中理所当然地应该包括唯一的一个最大的果子。 果子由 N-1根树枝连接起来,由于果树是一个整体,因此可以从任意一个果子出发沿着树枝“走到”任何一个其他的果子。
对于每段树枝,如果它所连接的两个果子需要由不同的头来吃掉,那么两个头会共同把树枝弄断而把果子分开;如果这两个果子是由同一个头来吃掉,那么这个头会懒得把它弄断而直接把果子连同树枝一起吃掉。当然,吃树枝并不是很舒服的,因此每段树枝都有一个吃下去的“难受值”,而九头龙的难受值就是所有头吃掉的树枝的“难受值”之和。
九头龙希望它的“难受值”尽量小,你能帮它算算吗?
例如图 1 所示的例子中,果树包含 8 个果子,7 段树枝,各段树枝的“难受值”标记在了树枝的旁边。九头龙有两个脑袋,大头需要吃掉 4 个果子,其中必须包含最大的果子。即 N=8,M=2,K=4:
最大的果子大头吃 4 个果子,用实心点标识;小头吃 4 个果子,用空心点标识;九头龙的难受值为 4,因为图中用细边标记的树枝被大头吃掉了。
【输入文件】
输入文件 dragon.in 的第 1 行包含三个整数 N (1<=N<=300), M (2<=M<=N),K (1<=K<=N)。 N 个果子依次编号 1,2,...,N,且 最大的果子的编号总是 1。
第 2行到第 N 行描述了果树的形态,每行包含三个整数 a (1<=a<=N), b (1<=b<=N),c (0<=c<=10 5 ),表示存在一段难受值为 c 的树枝连接果子 a 和果子 b。
【输出文件】
输出文件 dragon.out 仅有一行,包含一个整数,表示在满足“大头”的要求的前提下,九头龙的难受值的最小值。如果无法满足要求,输出-1。
【样例输入】
8 2 4
1 2 20
1 3 4
1 4 13
2 5 10
2 6 12
3 7 15
3 8 5
【样例输出】
4
【样例说明】
该样例对应于题目描述中的例子。
正解:树形DP
解题报告:
今天考试T4,居然是NOI原题。
显然是一道树形DP,但是我们考虑记录的状态是什么:f[0、1][i][j]表示以i为根结点的子树中1号吃了j个并且i不选或者选的最小值。同时记忆化。
直接分类讨论儿子结点选了多少个,总复杂度O(N^3)。
代码如下:
//It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const int MAXN = ;
LL inf;
int n,m,k,ecnt;
int first[MAXN],next[MAXN*],to[MAXN*];
int brother[MAXN],son[MAXN],lian[MAXN][MAXN];
bool vis[MAXN];
LL f[][MAXN][MAXN]; inline int getint()
{
int w=,q=; char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar(); if(c=='-') q=,c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar(); return q ? -w : w;
} inline void down(int x,int fa){
vis[x]=;
for(int i=first[x];i;i=next[i]) {
int v=to[i]; if(vis[v]) continue;
//printf("%d %d\n",v,brother[v]);
brother[v]=son[x]; son[x]=v; down(v,x);
}
} inline LL dfs(int x,int fa,int remain,int flag){
if(x==) { if(remain==) return ; else return -; }
if(f[flag][x][remain]!=-) return f[flag][x][remain];
LL minl=inf,nowl,nowr,suan;
for(int i=;i<=remain;i++) {
nowl=dfs(brother[x],fa,i,flag);
if(nowl==remain) nowr=-;
else nowr=dfs(son[x],x,remain-i-,);//选 /*if(nowl>=0) {
if(flag==1) { suan=nowl+nowr+lian[fa][x]; } else suan=nowl+nowr;
if(suan<minl) minl=suan; }
*/ if(nowl>= && nowr>=) {
if(flag==) { suan=nowl+nowr+lian[fa][x]; } else suan=nowl+nowr;
minl=min(minl,suan);
}
nowr=dfs(son[x],x,remain-i,);//不选
/*if(nowl>=0) {
if(flag==0 && m==2) suan=nowl+nowr+lian[fa][x]; else suan=nowl+nowr;
minl=min(minl,suan);
}*/
if(nowl>= && nowr>=) {
if(flag== && m==) suan=nowl+nowr+lian[fa][x]; else suan=nowl+nowr;
minl=min(minl,suan);
}
}
//printf("%d %d %d %d\n",x,fa,remain,flag);
if(minl==inf) f[flag][x][remain]=-inf; else f[flag][x][remain]=minl;
return f[flag][x][remain];
} inline void work(){
n=getint(); m=getint(); k=getint(); inf=; for(int i=;i<=;i++) inf*=;
int x,y,z;
for(int i=;i<n;i++) {
x=getint(); y=getint(); z=getint(); lian[x][y]=lian[y][x]=z;
next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y;
next[++ecnt]=first[y]; first[y]=ecnt; to[ecnt]=x;
}
if(m-+k>n) { printf("-1"); return ; }
down(,); memset(f,-,sizeof(f));
dfs(son[],,k-,);
printf("%lld",f[][son[]][k-]);
} int main()
{
work();
return ;
}
codevs1746 贪吃的九头龙的更多相关文章
- [codevs1746][NOI2002]贪吃的九头龙
[codevs1746][NOI2002]贪吃的九头龙 试题描述 传说中的九头龙是一种特别贪吃的动物.虽然名字叫"九头龙",但这只是说它出生的时候有九个头,而在成长的过程中,它有时 ...
- Vijos1523贪吃的九头龙【树形DP】
贪吃的九头龙 传说中的九头龙是一种特别贪吃的动物.虽然名字叫"九头龙",但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头 ...
- 贪吃的九头龙(tyvj P1523)
T2 .tyvj P1523贪吃的九头龙 描述 传说中的九头龙是一种特别贪吃的动物.虽然名字叫“九头龙”,但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于 ...
- Vijos 1523 贪吃的九头龙 【树形DP】
贪吃的九头龙 背景 安徽省芜湖市第二十七中学测试题 NOI 2002 贪吃的九头龙(dragon) Description:OfficialData:OfficialProgram:Converted ...
- [NOI2002]贪吃的九头龙(树形dp)
[NOI2002]贪吃的九头龙 题目背景 传说中的九头龙是一种特别贪吃的动物.虽然名字叫"九头龙",但这只是 说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的 ...
- vojis1523 NOI2002 贪吃的九头龙
描述 传说中的九头龙是一种特别贪吃的动物.虽然名字叫“九头龙”,但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头因衰老而自己脱落. 有一天, ...
- codevs贪吃的九头龙
传说中的九头龙是一种特别贪吃的动物.虽然名字叫“九头龙”,但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头因衰老而自己脱落.有一天,有M 个 ...
- [NOI2002] 贪吃的九头龙
题目类型:树形DP 传送门:>Here< 题意:有一只九头龙要吃了一颗树,给出一棵\(N\)个节点的带边权的树.九头龙有\(M\)个头,其中一个是大头,大头要吃恰好\(K\)个节点,其他头 ...
- Vijos1523 NOI2002 贪吃的九头龙 树形dp
思路不算很难,但细节处理很麻烦 前面建图.多叉转二叉,以及确定dp处理序列的过程都是套路,dp的状态转移过程以注释的形式阐述 #include <cstdio> #include < ...
随机推荐
- MongoDB学习(五)Linux环境安装MongoDB
一. 下载 从http://www.mongodb.org/downloads地址中下载:mongodb-linux-x86_64-2.4.11.tar 二. 安装 1>设置mongoDB ...
- jsp 微信公众平台 token验证(php、jsp)(转载)
微信公众平台现在推出自动回复消息接口,但是由于是接口内容用的是PHP语言写的,很多地方操作起来让本人这个对java比较熟悉的小伙很别扭,所以仿照PHP的接口代码做了一套jsp语言编写的接口. 首先先把 ...
- sp_executesql介绍和使用
原文:http://www.cnblogs.com/wanyuan8/archive/2011/11/09/2243483.html execute相信大家都用的用熟了,简写为exec,除了用来执行存 ...
- IIS mime类型
参考网站:http://www.iwms.net/n1381c2.aspx 以下例子为iis6.0 下载安卓.苹果安装包时候,需要添加mime类型才可以下载,否则访问不到 安卓 .apk appli ...
- 携手K2 BPM,华住酒店完美实现“互联网+”转型
华住酒店集团,旗下6大品牌酒店,包括商旅品牌—禧玥酒店.全季酒店.星程酒店.汉庭酒店.海友酒店,以及度假品牌—漫心度假酒店.高端大气上档次一气呵成,2013年签约K2,携手成就美好生活. 演讲人:宋洪 ...
- 千份位Javascript Thousand Separator / string format
function Separator(str){ return str.split(/(\d+)(\d{3})(\d{3})(\d{3})(\d{3})/).join(',').replace(/^, ...
- linux patch 格式与说明(收录)
转:http://blog.chinaunix.net/uid-26813001-id-3282954.html 首先介绍一下diff和patch.在这里不会把man在线文档上所有的选项都介绍一下,那 ...
- sed 4个功能
[root@lanny test]# cat test.txt test liyao lanny 经典博文: http://oldboy.blog.51cto.com/2561410/949365 h ...
- (OAF)jdeveloper集成log4j并将日志输出到指定文件并写入数据库
参考: How to configure Log4j in JDev 11g Ever wanted to use log4j in your adf project ? Well though Or ...
- android布局 FrameLayout(帧布局)详解
看到一篇很有趣的文章对我就是冲着萌妹子看的 FrameLayout(帧布局) 前言 作为android六大布局中最为简单的布局之一,该布局直接在屏幕上开辟出了一块空白区域, 当我们往里面添加组件的时候 ...