Uva-12093 Protecting Zonk(较复杂的树形DP)
来源:互联网 发布:ssd优化工具 编辑:程序博客网 时间:2024/06/15 09:14
题意:给定一个有n(n <= 10000) 个节点的无根树.有两种装置A和B,每种都有无线多个.
在某个节点x使用A装置需要C1(C1 <= 1000)的花费,并且此时与节点x相连的边都被覆盖.
在某个节点X使用B装置需要C2(C2 <= 1000)的费用,并且此时与节点x相连的边以及与节点x相连的点相连的边都被覆盖.
求覆盖所有边的最小花费.
分析:状态有很多种表示方法,f[u][a][b][c] 表示第i个点选了a装置,他父亲选了b装置,c表示它的儿子中是否有选C2装置,或者f[u][a][b][c]表示第i个点选了a装置,他父亲选了b装置,c表示u到fa[u]的边是否被u上边的点覆盖,这两种状态定义方法都能转移,其实这道题的状态表示方法不难想到,难就在这个状态猛一看很多,给人一种无从下手的感觉,其实手动列一下这18个状态就会发现它们的转移其实一共就三种类型.
第二种状态表示方法:
#include <bits/stdc++.h>#define N 10005#define INF 1047483647#define MOD 1000000007using namespace std;int n,u,v,c1,c2,f[N][3][3][2],dp[N][2];vector<int> G[N];void dfs(int u,int fa){for(int v : G[u]) if(v != fa) dfs(v,u);for(int i = 0;i < 3;i++) for(int j = 0;j < 3;j++) for(int k = 0;k < 2;k++) { if(!k && j) continue; f[u][i][j][k] = !i ? 0:(i == 1 ? c1 : c2); int t = 0,V_tot = 0; dp[0][1] = INF; for(int v : G[u]) if(v != fa) { t++; V_tot += min(min(f[v][0][i][i || (j==2)],f[v][1][i][i || (j==2)]),f[v][2][i][i || (j==2)]); dp[t][0] = dp[t-1][0] + min(f[v][0][i][1],f[v][1][i][1]); dp[t][1] = min(dp[t-1][1] + min(f[v][2][i][1],min(f[v][0][i][1],f[v][1][i][1])),dp[t-1][0] + f[v][2][i][0]); } if(!(i+j+k)) f[u][i][j][k] += dp[t][1]; else if(!i && j < 2) f[u][i][j][k] += min(dp[t][1],V_tot); else f[u][i][j][k] += V_tot; }}int main(){while(~scanf("%d%d%d",&n,&c1,&c2) && (n+c1+c2)){for(int i = 1;i <= n;i++) G[i].clear();for(int i = 1;i < n;i++){scanf("%d%d",&u,&v);G[u].push_back(v);G[v].push_back(u);}dfs(1,0);cout<<min(min(f[1][0][0][1],f[1][1][0][1]),f[1][2][0][1])<<endl;}}
第一种状态表示方法:
#include <bits/stdc++.h>#define N 10005#define INF 1047483647#define MOD 1000000007using namespace std;int n,u,v,c1,c2,f[N][3][3][2],dp[N][2];vector<int> G[N];void dfs(int u,int fa){for(int v : G[u]) if(v != fa) dfs(v,u);for(int i = 0;i < 3;i++) for(int j = 0;j < 3;j++) for(int k = 0;k < 2;k++) { f[u][i][j][k] = !i ? 0:(i == 1 ? c1 : c2); int t = 0; dp[0][1] = INF; for(int v : G[u]) if(v != fa) { t++; dp[t][0] = dp[t-1][0] + min(min(f[v][0][i][1],f[v][0][i][0]),min(f[v][1][i][1],f[v][1][i][0])); dp[t][1] = min(dp[t-1][1] + min(min(f[v][2][i][1],f[v][2][i][0]),min(min(f[v][0][i][1],f[v][0][i][0]),min(f[v][1][i][1],f[v][1][i][0]))),dp[t-1][0] + min(f[v][2][i][1],f[v][2][i][0])); } if(k == 1) f[u][i][j][k] += dp[t][1]; else if(!(i+k) && j < 2) { for(int v : G[u]) if(v != fa) f[u][i][j][k] += min(min(f[v][1][i][0],f[v][1][i][1]),f[v][0][i][1]); } else f[u][i][j][k] += dp[t][0]; }}int main(){while(~scanf("%d%d%d",&n,&c1,&c2) && (n+c1+c2)){for(int i = 1;i <= n;i++) G[i].clear();for(int i = 1;i < n;i++){scanf("%d%d",&u,&v);G[u].push_back(v);G[v].push_back(u);}dfs(1,0);cout<<min(min(min(f[1][0][0][1],f[1][0][0][0]),min(f[1][1][0][1],f[1][1][0][0])),min(f[1][2][0][1],f[1][2][0][0]))<<endl;}}
0 0
- Uva-12093 Protecting Zonk(较复杂的树形DP)
- uva 12093 Protecting Zonk 树形dp
- Uva 12093 Protecting Zonk
- Protecting Zonk UVA
- Protecting Zonk UVA
- uva 12093 Protecting Zonk(在某个节点X使用A装置,此时与节点X相连的边都被覆盖)
- UVa12093 Protecting Zonk
- UVA 12093 树形DP
- uva - 12093(树形dp)
- UVA - 10618(条件复杂的简单dp)
- uva 10859 树形dp
- uva 1292(树形dp)
- uva 1407(树形dp)
- uva 12223(树形dp)
- UVA 1218 (树形DP)
- uva 1292 树形dp
- uva 10859 树形dp
- UVA 10859【树形dp】
- JDK 安装详解
- python系列笔记二:Python容器:列表
- Windows下Eclipse+PyDev安装Python开发环境
- Accurate Scale Estimation for Robust Visual Tracking code
- JavaScript笔记(一)
- Uva-12093 Protecting Zonk(较复杂的树形DP)
- RabbitMQ的消息路由基本讲解
- 差分约束简述
- 谁获得了最高奖学金
- Nagios
- 2015 ICCV以及ICCV Workshop中有关Action Units(AU)检测和Facial landmark检测的文章总结
- freemarker学习--语法
- 《Java高并发程序设计》学习 --7.10 多个Actor同时修改数据:Agent
- 1039字符消除