Description

几乎整个Byteland王国都被森林和河流所覆盖。小点的河汇聚到一起,形成了稍大点的河。就这样,所有的河水都汇聚并流进了一条大河,最后这条大河流进了大海。这条大河的入海口处有一个村庄——名叫Bytetown 在Byteland国,有n个伐木的村庄,这些村庄都座落在河边。目前在Bytetown,有一个巨大的伐木场,它处理着全国砍下的所有木料。木料被砍下后,顺着河流而被运到Bytetown的伐木场。Byteland的国王决定,为了减少运输木料的费用,再额外地建造k个伐木场。这k个伐木场将被建在其他村庄里。这些伐木场建造后,木料就不用都被送到Bytetown了,它们可以在 运输过程中第一个碰到的新伐木场被处理。显然,如果伐木场座落的那个村子就不用再付运送木料的费用了。它们可以直接被本村的伐木场处理。 注意:所有的河流都不会分叉,也就是说,每一个村子,顺流而下都只有一条路——到bytetown。 国王的大臣计算出了每个村子每年要产多少木料,你的任务是决定在哪些村子建设伐木场能获得最小的运费。其中运费的计算方法为:每一块木料每千米1分钱。 编一个程序: .从文件读入村子的个数,另外要建设的伐木场的数目,每年每个村子产的木料的块数以及河流的描述。 .计算最小的运费并输出。
Input 第一行 包括两个数 n(<=n<=),k(<=k<=,且 k<=n)。n为村庄数,k为要建的伐木场的数目。除了bytetown外,每个村子依次被命名为1,,……n,bytetown被命名为0。 接下来n行,每行包涵3个整数 wi——每年i村子产的木料的块数 (<=wi<=) vi——离i村子下游最近的村子(或bytetown)(<=vi<=n) di——vi到i的距离(km)。(<=di<=) 保证每年所有的木料流到bytetown的运费不超过2000,,000分 %的数据中n不超过20。
Output 输出最小花费,精确到分。
Sample Input Sample Output

题目

   芒果君:人生中第一道IOI的题,看到来源我就蒙b了,看完题目我更蒙b了。对于树形DP,有一种便于操作的处理方式,叫做孩子父亲表示法,它可以将多叉树转化成二叉树,结点的左结点储存它的大儿子,右结点储存它的大弟弟,使得信息的传递变有序了。之后将两点距转成点到根的前缀和。由于要计算距离,这次的dp方程需要有三维,第三维是最近的伐木场(不一定是父节点哦)。考虑时间选择记忆化搜索,状态分建不建两种,不建,从0到容量;建,从0到容量减1,递归时将k变成i,最后输出f[0][m][0]。

 #include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define inf 1<<29
using namespace std;
int hl[],n,m,f[][][],cnt,dis[],lson[],rson[],val[];
struct X{
int u,v,ne,w,len;
}e[];
void add(int u,int v,int w)
{
e[++cnt].u=u;
e[cnt].v=v;
e[cnt].w=w;
e[cnt].ne=hl[u];
hl[u]=cnt;
}
void build(int x)
{
int t;
for(int i=hl[x];i;i=e[i].ne) build(e[i].v);
for(int i=hl[x];i;i=e[i].ne){
int v=e[i].v;
if(!lson[x]) lson[x]=t=v;
else{
rson[t]=v;
t=v;
}
}
}
void finddis(int x,int y)
{
for(int i=hl[x];i;i=e[i].ne){
int v=e[i].v,w=e[i].w;
if(v==y) continue;
dis[v]=dis[x]+w;
finddis(v,x);
}
}
int dp(int i,int j,int k)
{
if(f[i][j][k]!=-) return f[i][j][k];
f[i][j][k]=inf;
for(int t=;t<=j;++t){
int tmp=;
if(lson[i]) tmp+=dp(lson[i],t,k);
if(rson[i]) tmp+=dp(rson[i],j-t,k);
f[i][j][k]=min(f[i][j][k],tmp+(dis[i]-dis[k])*val[i]);
}
for(int t=;t<j;++t){
int tmp=;
if(lson[i]) tmp+=dp(lson[i],t,i);
if(rson[i]) tmp+=dp(rson[i],j-t-,k);
f[i][j][k]=min(f[i][j][k],tmp);
}
return f[i][j][k];
}
int main()
{
int x,y,w;
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i){
scanf("%d%d%d",&w,&x,&y);
val[i]=w;
add(x,i,y);
}
build();
finddis(,);
memset(f,-,sizeof(f));
printf("%d",dp(,m,));
return ;
}

IOI 2005/bzoj 1812:riv 河流的更多相关文章

  1. BZOJ.1812.[IOI2005]Riv 河流(树形背包)

    BZOJ 洛谷 这个数据范围..考虑暴力一些把各种信息都记下来.不妨直接令\(f[i][j][k][0/1]\)表示当前为点\(i\),离\(i\)最近的建了伐木场的\(i\)的祖先为\(j\),\( ...

  2. BZOJ 1812: [Ioi2005]riv( 树形dp )

    树背包, 左儿子右兄弟来表示树, dp(x, y, z)表示结点x, x的子树及x的部分兄弟共建y个伐木场, 离x最近的伐木场是z时的最小代价. 时间复杂度O(N^2*K^2) ----------- ...

  3. 洛谷P3354 Riv河流 [IOI2005] 树型dp

    正解:树型dp 解题报告: 传送门! 简要题意:有棵树,每个节点有个权值w,要求选k个节点,最大化∑dis*w,其中如果某个节点到根的路径上选了别的节点,dis指的是到达那个节点的距离 首先这个一看就 ...

  4. [LUOGU] P3354 [IOI2005]Riv 河流

    题目描述 几乎整个Byteland王国都被森林和河流所覆盖.小点的河汇聚到一起,形成了稍大点的河.就这样,所有的河水都汇聚并流进了一条大河,最后这条大河流进了大海.这条大河的入海口处有一个村庄--名叫 ...

  5. [IOI2005]Riv河流

    题目链接:洛谷,BZOJ 前置知识:莫得 题解 直接考虑dp.首先想法是设状态 \(dp[u][i]\) 表示u的子树内建 \(i\) 个伐木场且子树内木头都运到某个伐木场的最小花费.发现这样的状态是 ...

  6. IOI 2005 River (洛谷 3354)

    题目描述 几乎整个Byteland王国都被森林和河流所覆盖.小点的河汇聚到一起,形成了稍大点的河.就这样,所有的河水都汇聚并流进了一条大河,最后这条大河流进了大海.这条大河的入海口处有一个村庄--名叫 ...

  7. [HAOI 2005][BZOJ 1054] 移动玩具

    先贴一波题面 1054: [HAOI2008]移动玩具 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2288  Solved: 1270 Descr ...

  8. bzoj 1812

    什么鬼noip互测题... 这题很显然是树形dp,但设计状态以及转移是个难点 记状态f[i][j][k]表示以i为根节点的子树,离i最近的祖宗节点编号为j放了虫洞(伐木场?),i的子树内放了k个伐木场 ...

  9. P3354 [IOI2005]Riv 河流

    树形dp,设f[i][j][k]表示第i个点的子树中选择j个点作为伐木场,而且k是建了伐木场的最浅的i的祖先的情况下,最小的收益. 这种题还要练一下,咕咕 然后转移可以n4方做. // luogu-j ...

随机推荐

  1. HDU 6150 - Vertex Cover | 2017 中国大学生程序设计竞赛 - 网络选拔赛

    思路来自 ICPCCamp /* HDU 6150 - Vertex Cover [ 构造 ] | 2017 中国大学生程序设计竞赛 - 网络选拔赛 题意: 给了你一个贪心法找最小覆盖的算法,构造一组 ...

  2. ArrayBuffer、TypedArray、DataView二进制数组

    三个是处理二进制数据的接口.都是类数组. 1.ArrayBuffer是什么? ArrayBuffer是一个二进制对象(文件,图片等).它指向固定长度的,连续的内存区域. const buffer = ...

  3. spring 定时任务的 执行时间设置规则-----看完这篇就懂了

    单纯针对时间的设置规则 org.springframework.scheduling.quartz.CronTriggerBean允许你更精确地控制任务的运行时间,只需要设置其cronExpressi ...

  4. CF915E 动态开线段树

    CF915E 动态开线段树 题面 因为\(n\le10^9\),所以动态开点,线段树维护\([1,n]\)天非工作日数量. 之前的结构体写法被卡了,只能改成函数传l,r(虽然也不难) 动态开点好写,但 ...

  5. LOJ2537. 「PKUWC2018」Minimax [DP,线段树合并]

    传送门 思路 首先有一个\(O(n^2)\)的简单DP:设\(dp_{x,w}\)为\(x\)的权值为\(w\)的概率. 假设\(w\)来自\(v1\)的子树,那么有 \[ dp_{x,w}=dp_{ ...

  6. java微服务简介与实战

    今年做了一段时间的可见光.ceph存储,后端开发微服务项目,在这记录点东西,也方便大家借鉴查找. springboot的项目实例:https://github.com/ityouknow/spring ...

  7. jvm 线程状态

    NEW: Just starting up, i.e., in process of being initialized.NEW_TRANS: Corresponding transition sta ...

  8. js循环数组(总结)

    js循环数组(总结) 一.总结 一句话总结: for循环:for(j = 0,len=arr.length; j < len; j++) {} foreach循环:arr.forEach((it ...

  9. Qt自定义委托在QTableView中绘制控件、图片、文字

    自定义委托,继承于,QStyledItemDelegate类,重载Paint()函数, 1.实现在QTableView中绘制 格式字符串 2.实现在QTableView中绘制进度条 3.实现在QTab ...

  10. python 调用github的api,呈现python的受欢迎的程度

    1 使用api调用数据: 在浏览器的地址栏中输入: https://api.github.com/search/repositories?q=language:python&sort=star ...