3090: Coci2009 [podjela]

Description

有 N 个农民, 他们住在 N 个不同的村子里. 这 N 个村子形成一棵树.
每个农民初始时获得 X 的钱.
每一次操作, 一个农民可以从它自己的钱中, 取出任意数量的钱, 交给某个相邻村子的农民.

对于每个农民给定一个值 v_i, 求
    (1) 最少需要多少次操作, 使得每个农民最终拿到的钱 >= 给定的值.

Input

第1行: 一个整数 N (1 <= N <= 2000)
    第2行: 一个整数 X (0 <= X <= 10000)
    第3行: N 个整数, 表示 v_i. 保证所有 v_i 的和 <= N * X
    第4..N+2行: 每行两个 1..N 的数, 表示树上的一条边. 边是双向的.

Output

第1行: 一个整数, 最少需要的操作次数

Sample Input

6
15
10 20 18 16 6 16
1 4
4 5
4 6
6 2
5 3

Sample Output

5

HINT

Source

【分析】

  之前做过很多次这种移来移去的题目了。

  如果有环的,我就做过BZOJ 1045 一道数学题。

  如果没环,目标值的和等于初始值的和,那么挺唯一的,直接for就好了。

  这题就是目标值的和小于等于初始值的和的,考虑DP。

  一开始的想法当然是f[x][y]表示x这个子树,然后y这个点的值,然后什么最小代价。

  但是爆空间超时啊,不如把f中的y和答案换一下位置,因为显然操作次数少于子树大小,

  f[x][y]表示x这棵子树在操作y次之后满足目标值,最少要x从父亲那里拿多少东西(若f的值小于0则表示不仅不用从父亲那里拿东西,还可以给-f[x][y]的东西给父亲)

  然后DP。

  这种要满足每个子树的题我真的是不太擅长,于是我最好的解决方案就是滚动一下了。

  还有要注意的是x<=n,y<=x,所以看似三重循环,实际是n^2的,这个是之前做树形依赖的题知道的,因为可以看成只会在LCA的时候for到那两个东西。

  

  大神的方法跟我的差不多然后讲的比我清楚:http://blog.csdn.net/visit_world/article/details/54297322

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 2010
#define INF 0xfffffff int mymin(int x,int y) {return x<y?x:y;}
int mymax(int x,int y) {return x>y?x:y;} int w[Maxn],ww; struct node
{
int x,y,next;
}t[Maxn*];
int first[Maxn],len; void ins(int x,int y)
{
t[++len].x=x;t[len].y=y;
t[len].next=first[x];first[x]=len;
} int f[Maxn][Maxn],g[][Maxn],sm[Maxn]; void dfs(int x,int ff)
{
sm[x]=;
for(int i=first[x];i;i=t[i].next) if(t[i].y!=ff)
{
int y=t[i].y;
dfs(y,x);
sm[x]+=sm[y];
}
if(sm[x]!=)
{
int p=;
for(int j=;j<=sm[x];j++) g[][j]=;
for(int i=first[x];i;i=t[i].next) if(t[i].y!=ff)
{
int y=t[i].y;
for(int j=;j<=sm[x];j++) g[-p][j]=INF;
//j-k<=sm[x]-1-sm[y]
//k>=j-sm[x]+sm[y]+1
for(int j=;j<=sm[x];j++)
{
int st=mymax(j-sm[x]+sm[y]+,);
for(int k=st;k<=sm[y];k++)
{
if(k>j) break;//j-k>=0
if(f[y][k]>)
{
if(k>=) g[-p][j]=mymin(g[-p][j],g[p][j-k]+f[y][k-]);
}
else
{
if(k>=) g[-p][j]=mymin(g[-p][j],g[p][j-k]+f[y][k-]);//give father
if(k!=sm[y]) g[-p][j]=mymin(g[-p][j],g[p][j-k]);
}
}
}
p=-p;
}
for(int j=;j<sm[x];j++) f[x][j]=g[p][j];
}
for(int j=;j<sm[x];j++)
{
f[x][j]=f[x][j]+w[x]-ww;
// printf("f[%d][%d]=%d\n",x,j,f[x][j]);
}
} int main()
{
int n;
scanf("%d%d",&n,&ww);
len=;
memset(first,,sizeof(first));
for(int i=;i<=n;i++) scanf("%d",&w[i]);
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y);ins(y,x);
}
memset(f,,sizeof(f));
dfs(,);
for(int i=;i<sm[];i++) if(f[][i]<=) {printf("%d\n",i);break;}
return ;
}

2017-03-22 10:26:09

【BZOJ 3090】 树形DP的更多相关文章

  1. BZOJ 1040 树形DP+环套树

    就是有n个点n条边,那么有且只有一个环那么用Dfs把在环上的两个点找到.然后拆开,从这条个点分别作树形Dp即可. #include <cstdio> #include <cstrin ...

  2. BZOJ - 2500 树形DP乱搞

    题意:给出一棵树,两个给给的人在第\(i\)天会从节点\(i\)沿着最长路径走,求最长的连续天数\([L,R]\)使得\([L,R]\)为起点的最长路径极差不超过m 求\(1\)到\(n\)的最长路经 ...

  3. BZOJ 4033 树形DP

    http://blog.csdn.net/mirrorgray/article/details/51123741 安利队长blog- 树形dp吧,状态挺显然的,dp[x][j]表示以x为根的子树中,选 ...

  4. BZOJ 4987 (树形DP)

    ###题面 https://www.lydsy.com/JudgeOnline/problem.php?id=4987 ###分析 先考虑贪心,显然k个节点形成一棵树 求出树的直径,显然直径应该只被经 ...

  5. [USACO10MAR]伟大的奶牛聚集 BZOJ 1827 树形dp+dfs

    题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...

  6. bzoj 4007 树形dp

    题目大意 脸哥最近来到了一个神奇的王国,王国里的公民每个公民有两个下属或者没有下属,这种关系刚好组成一个 n 层的完全二叉树.公民 i 的下属是 2 * i 和 2 * i +1.最下层的公民即叶子节 ...

  7. BZOJ 1369 树形DP

    思路: f[i][j] 表示节点i 染成j时 子树的最小权值 (我会猜这个j很小 你打我吖~) 随便DP一发就好了 (证明我也不会) //By SiriusRen #include <cstdi ...

  8. [BZOJ 4033] [HAOI2015] T1 【树形DP】

    题目链接:BZOJ - 4033 题目分析 使用树形DP,用 f[i][j] 表示在以 i 为根的子树,有 j 个黑点的最大权值. 这个权值指的是,这个子树内部的点对间距离的贡献,以及 i 和 Fat ...

  9. [BZOJ 1907] 树的路径覆盖 【树形DP】

    题目链接:BZOJ - 1907 题目分析 使用树形 DP,f[x][0] 表示以 x 为根的子树不能与 x 的父亲连接的最小路径数(即 x 是一个折线的拐点). f[x][1] 表示以 x 为根的子 ...

  10. bzoj 4871: [Shoi2017]摧毁“树状图” [树形DP]

    4871: [Shoi2017]摧毁"树状图" 题意:一颗无向树,选两条边不重复的路径,删去选择的点和路径剩下一些cc,求最多cc数. update 5.1 : 刚刚发现bzoj上 ...

随机推荐

  1. 集合框架小结-List

    List集合存储的元素是有序的,可重复的,有索引 List特有方法: 增加 add(index, element); addAll(index, Collection); 删除 remove(inde ...

  2. 【Ural】1519. Formula 1 插头DP

    [题目]1519. Formula 1 [题意]给定n*m个方格图,有一些障碍格,求非障碍格的哈密顿回路数量.n,m<=12. [算法]插头DP [题解]<基于连通性状态压缩的动态规划问题 ...

  3. 使sqoop能够启用压缩的一些配置

    在使用sqoop 将数据库表中数据导入至hdfs时 配置启用压缩 hadoop 的命令    检查本地库支持哪些  bin/hadoop checknative 需要配置native    要编译版本 ...

  4. Linux下文本浏览器lynx

    一般登录到Linux上的时候都是使用Shell登录上去的,但是如果这个时候我们有浏览网页的需求怎么办,比如我刚刚部署上去一个网站,但是我并不知道我有没有部署成功,而且只能在这一台Linux上能够访问到 ...

  5. 2、java语言基础

    1.关键字 被Java语言赋予特定含义的单词被称为关键字关键字都是小写的在Java开发工具中,针对关键字有特殊颜色的标记 2.标识符 Java标识符命名规则 ·标识符是由,数字,字母,下划线和美元符号 ...

  6. 根据 plist 还原 图片

    1. python 环境自己配置(支持windows Mac ) 2. 把所有的 plist  和 大图片放到一个目录下 3.如果添加了 系统环境变量 就直接双击运行脚本,如果没有设置,把脚本拽到DO ...

  7. mysql安装后开启远程

    操作系统为centos7 64 1.修改 /etc/my.cnf,在 [mysqld] 小节下添加一行:skip-grant-tables=1 这一行配置让 mysqld 启动时不对密码进行验证 2. ...

  8. linux配置samba服务【原创】

    转载请注明出处http://www.cnblogs.com/paul8339/p/7509981.html 需求,windows服务器访问linux的共享文件,需要linux服务器安装并配置samba ...

  9. Selenium_Grid

    Selenium Grid 工作原理 Grid是一种分布式测试工具,整个结果由一个hub主节点和若干个node代理节点组成. hub用来管理各个代理节点的注册和状态信息,并且接收远程客户端代码请求调用 ...

  10. 关于Windows中的硬链接

    https://zhidao.baidu.com/question/748233720330351012.html linux中使用硬链接 ln a.txt b.txt 查看硬链接 ls -il 关于 ...