【BZOJ1812】[Ioi2005]riv

Description

几乎整个Byteland王国都被森林和河流所覆盖。小点的河汇聚到一起,形成了稍大点的河。就这样,所有的河水都汇聚并流进了一条大河,最后这条大河流进了大海。这条大河的入海口处有一个村庄——名叫Bytetown 在Byteland国,有n个伐木的村庄,这些村庄都座落在河边。目前在Bytetown,有一个巨大的伐木场,它处理着全国砍下的所有木料。木料被砍下后,顺着河流而被运到Bytetown的伐木场。Byteland的国王决定,为了减少运输木料的费用,再额外地建造k个伐木场。这k个伐木场将被建在其他村庄里。这些伐木场建造后,木料就不用都被送到Bytetown了,它们可以在 运输过程中第一个碰到的新伐木场被处理。显然,如果伐木场座落的那个村子就不用再付运送木料的费用了。它们可以直接被本村的伐木场处理。 注意:所有的河流都不会分叉,也就是说,每一个村子,顺流而下都只有一条路——到bytetown。 国王的大臣计算出了每个村子每年要产多少木料,你的任务是决定在哪些村子建设伐木场能获得最小的运费。其中运费的计算方法为:每一块木料每千米1分钱。 编一个程序: 1.从文件读入村子的个数,另外要建设的伐木场的数目,每年每个村子产的木料的块数以及河流的描述。 2.计算最小的运费并输出。

Input

第一行 包括两个数 n(2<=n<=100),k(1<=k<=50,且 k<=n)。n为村庄数,k为要建的伐木场的数目。除了bytetown外,每个村子依次被命名为1,2,3……n,bytetown被命名为0。 接下来n行,每行包涵3个整数 wi——每年i村子产的木料的块数 (0<=wi<=10000) vi——离i村子下游最近的村子(或bytetown)(0<=vi<=n) di——vi到i的距离(km)。(1<=di<=10000) 保证每年所有的木料流到bytetown的运费不超过2000,000,000分 50%的数据中n不超过20。

Output

输出最小花费,精确到分。

Sample Input

4 2
1 0 1
1 1 10
10 2 5
1 2 3

Sample Output

4

题解:憋了一上午想出来的树形DP题~

如何设状态呢?显然n=100,应该是3维的状态,并且有一维是x,有一维是x的子树中建了多少个伐木场,最后一维呢?用y表示x最近的建了伐木场的祖先!

状态都设完了就做完了~用f[x][y][z]表示x子树中建y个伐木场,并且x的木料运到x的z级祖先的最小花费。那么对于y这一维相当于树形背包。对于z这一维,它的儿子运到的位置一定不会比x的z级祖先更远,那么就用f[x][y][z]和f[x'][y'][z'](x'是x的儿子,z'<=z+1)来更新f'[x][y+y'][z]即可。

网上的代码怎么都是左儿子右兄弟啊~

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
int n,m,cnt;
ll ans;
int to[110],next[110],head[110],fa[110][110],sf[110],siz[110],w[110],v[110],dep[110];
ll f[110][110][110],g[110][110];
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
inline void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
void dfs(int x)
{
int i,j,k,l,y;
fa[x][0]=x,siz[x]=1;
for(i=0;i<=sf[x];i++) y=fa[x][i],f[x][i][!i]=(dep[x]-dep[y])*w[x];
for(i=head[x];i!=-1;i=next[i])
{
y=to[i],dep[y]=dep[x]+v[y];
for(j=0;j<=sf[x];j++) fa[y][++sf[y]]=fa[x][j];
dfs(y);
memset(g,0x3f,sizeof(g));
for(j=0;j<=sf[x];j++) for(k=min(m,siz[x]);k>=0;k--) for(l=min(m-k,siz[y]);l>=0;l--)
g[j][k+l]=min(g[j][k+l],f[x][j][k]+min(f[y][j+1][l],f[y][0][l]));
siz[x]+=siz[y];
for(j=0;j<=sf[x];j++) for(k=0;k<=min(m,siz[x]);k++) f[x][j][k]=g[j][k];
}
}
int main()
{
n=rd(),m=rd()+1;
memset(head,-1,sizeof(head));
int i;
for(i=1;i<=n;i++) w[i]=rd(),add(rd(),i),v[i]=rd();
memset(f,0x3f,sizeof(f));
dfs(0);
printf("%lld",f[0][0][m]);
return 0;
}

【BZOJ1812】[Ioi2005]riv 树形DP的更多相关文章

  1. BZOJ1812: [Ioi2005]riv(树形dp)

    题意 题目链接 Sol 首先一个很显然的思路是直接用\(f[i][j] / g[i][j]\)表示\(i\)的子树中选了\(j\)个节点,该节点是否选的最小权值.但是直接这样然后按照树形背包的套路转移 ...

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

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

  3. BZOJ_1812_[Ioi2005]riv_树形DP

    BZOJ_1812_[Ioi2005]riv_树形DP Description 几乎整个Byteland王国都被森林和河流所覆盖.小点的河汇聚到一起,形成了稍大点的河.就这样,所有的河水都汇聚并流进了 ...

  4. bzoj1812 [Ioi2005]riv

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

  5. bzoj1812 [IOI2005]riv河流

    题目链接 problem 给出一棵树,每个点有点权,每条边有边权.0号点为根,每个点的代价是这个点的点权\(\times\)该点到根路径上的边权和. 现在可以选择最多K个点.使得每个点的代价变为:这个 ...

  6. [bzoj1812][IOI2006]riv_多叉树转二叉树_树形dp

    riv bzoj-1812 IOI-2006 题目大意:给定一棵n个点树,要求在上面建立k个收集站.点有点权,边有边权,整棵树的代价是每个点的点权乘以它和它的最近的祖先收集站的距离积的和. 注释:$1 ...

  7. rivers ioi2005 树形dp

    说句实话,写完这道题,很想吐一口血出来,以示我心情的糟糕: 题目很简单,树形dp,正常做30分钟,硬是做了好几个小时,真是伤心. 题解不写了,只是吐个槽,网上没有用背包写的dp,全是左儿子右兄弟写法, ...

  8. 洛谷P3354 [IOI2005]Riv 河流——“承诺”DP

    题目:https://www.luogu.org/problemnew/show/P3354 状态中要记录一个“承诺”,只需相同承诺之间相互转移即可: 然后就是树形DP的套路了. 代码如下: #inc ...

  9. 1812: [Ioi2005]riv

    1812: [Ioi2005]riv Time Limit: 10 Sec Memory Limit: 64 MB Submit: 635 Solved: 388 [Submit][Status][D ...

随机推荐

  1. Solution of NumberOfDiscIntersections by Codility

    question:https://codility.com/programmers/lessons/4 this question is seem like line intersections qu ...

  2. php核心技术与最佳实践知识点(下)

    九.缓存 1.缓存三大要素:命中率, 缓存更新策略,缓存最大数据量 2.命中率(mysql为例):mysql提供了一系列的query cache的global status来提现数据库缓存的情况: s ...

  3. 原生 javascript 基础回顾

    (1)打开新窗口 语法: window.open([URL], [窗口名称], [参数字符串]) 参数说明: URL:可选参数,在窗口中要显示网页的网址或路径.如果省略这个参数,或者它的值是空 字符串 ...

  4. Smooks转换设计

    Smooks转换设计 背景 不同的合作银行对应的外部接口是不一样的,我们需要把外部这些变化不定的接口格式,转换为我们银保通系统可以识别的内部接口.Smooks可以很好的解决这一问题.并且,当合作银行的 ...

  5. CKEditor的安装与基本使用(JSP)

    文章分类:Web前端 一.下载CKEditor 1. 直接下载地址.当前最新版本号为3.5: http://download.cksource.com/CKEditor/CKEditor/CKEdit ...

  6. angular4 开发记录

    1,传值问题 page setValue:  [routerLink]="['/product-details', product.id]"> ts     seValue: ...

  7. VMware Workstation 10安装详解

    虚拟机软件可让你在一个操作系统上直接运行的多个不同的虚拟操作系统,譬如可在 Windows 8.1 上运行 Ubuntu 或 Win7 等.免费的 VMware Player 和 VirtualBox ...

  8. Atitit  OOCSS vs bem

    Atitit  OOCSS vs bem     1. 今天最流行的CSS开发框架技术当属OOCSS,尽管还有其他类似的技术存在,如BEM.1 2. CSS设计模式:OOCSS 和 SMACSS1 2 ...

  9. eclipse代码凝视之模板xml

    曾经在eclipse中配置凝视的时候,都是各自在自己电脑上配置凝视,每一个同事风格不一样,并且配置繁琐.假设新来的同事忘了提醒,可能就没有配置凝视了.所以我就把类.方法的凝视写成xml文件.然后将配置 ...

  10. Building Maintainable Software-java篇之Separate Concerns in Modules

    Building Maintainable Software-java篇之Separate Concerns in Modules   In a system that is both complex ...