HDU 4340
好题一道啦。做这题时,抓住两个问题:一、给某点染色时,其连通的点是否已有一点以全部代价染色。二、该点染什么颜色。
嗯。第二个问题很容易,但第一个问题不容易了。我一开始就考虑祖父子三层结点的关系,认为在父结点时,要么子结点已染色,要么父结点已染色%#……*&¥%#……
很复杂。。。。
这是条件定得过于严格了,所以走不通。看了题解后,发现,可以把状态条件设得宽一点。
设dp[rt][0][0]为以rt为根的子树内,rt染0颜色,与其连通的块(同色,在子树内的)中,没有一个节点是以全部代价染色的,即没有入口点。
dp[rt][0][1]则为以rt为根的子树内,rt染0颜色,与其连通的块(同色,在子树内的)中,存在一个节点是以全部代价染色的。感觉这个存在实现设得妙,只要存在就可以,条件放宽了许多。
对于dp[r][1][0],dp[r][1][1]有同样的定义。
于是dp[rt][0][0]=sum(min(dp[son][0][0],dp[son][1][1]))+costrt/2;
dp[rt][0][1]=sum(min(dp[son][0][0],dp[son][1][1]))+min(costrt,costrt/2+min(dp[son][0][1]-min(dp[son][0][0],dp[son][1][1]))).解释一下min(dp[son][0][1]-min(dp[son][0][0],dp[son][1][1])。这是把子结点以根的子树状态转化为dp[rt][0][1]的最小代价,其中min(dp[son][0][0],dp[son][1][1])与方程开始的min(dp[son][0][0],dp[son][1][1])是一致的,因而又是一个巧妙的地方。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#define N 110 using namespace std;
int costA[N],costB[N]; int dp[N][][]; struct edge{
int u,v;
int next;
}Edge[N*];
int n,tot;
int head[N]; void addedge(int u,int v){
Edge[tot].u=u;
Edge[tot].v=v;
Edge[tot].next=head[u];
head[u]=tot++;
} void dfs(int now,int pre){
bool leaf=true;
int sum0=,sum1=;
int CA=(<<),CB=(<<);
for(int e=head[now];e!=-;e=Edge[e].next){
int v=Edge[e].v;
if(v!=pre){
leaf=false;
dfs(v,now);
sum0+=min(dp[v][][],dp[v][][]);
sum1+=min(dp[v][][],dp[v][][]);
CA=min(CA,dp[v][][]-min(dp[v][][],dp[v][][])+costA[now]/);
CB=min(CB,dp[v][][]-min(dp[v][][],dp[v][][])+costB[now]/);
}
}
if(leaf){
dp[now][][]=costA[now]/;
dp[now][][]=costA[now];
dp[now][][]=costB[now]/;
dp[now][][]=costB[now];
}
else{
dp[now][][]=sum0+costA[now]/;
dp[now][][]=sum0+min(costA[now],CA);
dp[now][][]=sum1+costB[now]/;
dp[now][][]=sum1+min(costB[now],CB);
}
} int main(){
int u,v;
while(scanf("%d",&n)!=EOF){
tot=;
memset(head,-,sizeof(head));
for(int i=;i<=n;i++)
scanf("%d",&costA[i]);
for(int i=;i<=n;i++)
scanf("%d",&costB[i]);
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
dfs(,);
printf("%d\n",min(dp[][][],dp[][][]));
}
return ;
}
HDU 4340的更多相关文章
- hdu 4340 树状DP
思路:我们定义两个数组,ant[Maxn][2],bob[Maxn][2].ant[i][0]表示还未确定哪个城市被全费用占领,ant[i][1]表示确定了哪个城市被全费用占领.那么ant[i][0] ...
- 【HDU - 4340】Capturing a country(树形DP)
BUPT2017 wintertraining(15) #8A 题意 n(<100)个城市组成的树.A攻击i城市需要a[i]代价,B需要b[i].如果一个城市的邻居被A攻击了,那么A攻击它只要A ...
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
- hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
- HDU 4569 Special equations(取模)
Special equations Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- HDU 4006The kth great number(K大数 +小顶堆)
The kth great number Time Limit:1000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64 ...
- HDU 1796How many integers can you find(容斥原理)
How many integers can you find Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d ...
- hdu 4481 Time travel(高斯求期望)(转)
(转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...
随机推荐
- C C++每个头文件的功能说
C/C++每个头文件的功能说明 传统 C++ #include <assert.h> //设定插入点 #include <ctype.h> //字符处理 #include &l ...
- [POI 2007] 堆积木
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1109 [算法] DP [代码] #include<bits/stdc++.h& ...
- [JXOI 2018] 守卫 解题报告 (DP)
interlinkage: https://www.luogu.org/problemnew/show/P4563 description: solution: 注意到对于范围$[l,r]$,$r$这 ...
- js 对象方法、类方法、原型方法区别
function People(name){this.name=name;//对象方法this.Introduce=function(){alert("My name is "+t ...
- LeetCode Weekly Contest 21
1. 530. Minimum Absolute Difference in BST 最小的差一定发生在有序数组的相邻两个数之间,所以对每一个数,找他的前驱和后继,更新结果即可!再仔细一想,bst的中 ...
- guice基本使用,配置模块的两种方式(三)
guice是使用module进行绑定的,它提供了两种方式进行操作. 第一种是继承AbstractModule抽象类. package com.ming.user.test; import com.go ...
- Npgsql使用入门(三)【批量导入数据】
Program.cs代码: class Program { static void Main(string[] args) { var test = new PgBulkCopyHelper<S ...
- delphi 用idhttp做web页面数据抓取 注意事项
这里不讨论webbrowse方式了 .直接采用indy的 idhttp Get post 可以很方便的获取网页数据. 但如果要抓取大量数据 程序稳定运行不崩溃就不那么容易了.这几年也做了不少类似工具 ...
- ajax获取跨域数据
1.效果图 2.源码 <%@ page contentType="text/html;charset=UTF-8" language="java" %&g ...
- sql server中使用组合索引需要注意的地方
一.使用组合索引需要注意的地方 1.索引应该建在选择性高的字段上(键值唯一的记录数/总记录条数),选择性越高索引的效果越好.价值越大,唯一索引的选择性最高: 2.组合索引中字段的顺序,选择性越高的字段 ...