HDU4340 Capturing a country DP
自己原来写的两个维度的DP有错,看了半天这个大牛的blog。http://blog.csdn.net/cyberzhg/article/details/7840922
题意:A军队和B军队要一起占领一个国家,城市和城市之间有一些双向边(但是没有环)。A军队要占领i城市需要a[i]的代价,B军队需要b[i]的代价。
若果A军队占领了i城市,i城市和j城市相邻,则A军队占领j城市只要a[i]/2的代价,B军队同理。问两个军队一起占领所有城市所需要花费的最小代价是多少。
解题过程上上述解题报告,再加几点自己的理解
f[i][0][0]表示的是以i用A军队进行进攻,且其所有选A军队的孩子选择半价的代价。
f[i][0][0] 和f[i][1][0]是一个辅助状态。
f[i][0][1]和f[i][1][1]才是正解。
对于”选择一个儿子付出代价,这个代价必须最小:min(dp[v][0][1] - min(dp[v][0][0], dp[v][1][0]));“
这个转移方程的理解要从dp[u][0][1] = min(SA + A[u], SA + A[u] / 2 + DA);来分析
SA+A[u]/2+DA=sum{min(dp[v][0][0], dp[v][1][1])}+A[u]/2+min(dp[v][0][1] - min(dp[v][0][0], dp[v][1][0]));
注意黄色表示的两个量相同。
假设min(dp[v][0][0],dp[v][1][1])= tmp[v];
则表达式可以清楚得写成SA+A[u]/2+DA=tm[1]+tmp[2]+tmp[3]+...tmp[sonSize]+min(dp[v][0][1]-tmp[j]) +A[u]/2;
=min{dp[v][0][1]+tmp[1]+tmp[2]+tmp[3]+...tmp[j-1]+tmp[j+1]+...+tmp[sonSize}+ A[u]/2;
可以理解成已知一个数列的加和sum,现在改变其中a[i]成为p。。则新的加和为sum-a[i]+p;
方程长确实比较不喜欢看。
代码实现的时候死在#define min(a,b) ((a)>(b)? (b):(a))上面了,我竟然不知道。。好吧,引以为戒。。
#include <stdio.h>
#include <string.h>
#define MAXN 105
#define min(a,b) ((a)>(b)? (b):(a))
int f[MAXN][][];
int a[MAXN];
int b[MAXN];
int map[MAXN][MAXN];
int dp(int i, int j,int k,int fa)
{
if (f[i][j][k] != -)
return f[i][j][k];
if (map[i][] == && fa != -)
{ f[i][][]=a[i]/;
f[i][][]=a[i];
f[i][][]=b[i]/;
f[i][][]=b[i];
return f[i][j][k];
}
int son;
int SA=;
int SB=,DA=,DB=;
// if (i == 2) printf("!!!");
for (int p = ; p <= map[i][]; p++)
if (map[i][p] != fa)
{
son=map[i][p];
SA+=min(dp(son,,,i),dp(son,,,i));
SB+=min(dp(son,,,i),dp(son,,,i));
DA=min(DA,dp(son,,,i)-min(dp(son,,,i),dp(son,,,i)));
DB=min(DB,dp(son,,,i)-min(dp(son,,,i),dp(son,,,i)));
}
f[i][][]=SA+a[i]/;
f[i][][]=SB+b[i]/;
f[i][][]=min(SA+a[i],SA+a[i]/+DA);
f[i][][]=min(SB+b[i],SB+b[i]/+DB); }
int main()
{
int i,j,m,n;
int x,y,k;
while (scanf("%d", &n) != EOF)
{
for (i = ; i <= n; i++)
scanf("%d", &a[i]);
for (i = ; i <=n; i++)
scanf("%d", &b[i]);
memset(map,,sizeof(map));
memset(f,-,sizeof(f));
for (i = ; i <n; i++)
{
scanf("%d%d",&x,&y);
map[x][++map[x][]]=y;
map[y][++map[y][]]=x;
}
printf("%d\n",min(dp(,,,-),dp(,,,-)));
}
return ;
}
HDU4340 Capturing a country DP的更多相关文章
- 【HDU - 4340】Capturing a country(树形DP)
BUPT2017 wintertraining(15) #8A 题意 n(<100)个城市组成的树.A攻击i城市需要a[i]代价,B需要b[i].如果一个城市的邻居被A攻击了,那么A攻击它只要A ...
- HDU 5723 Abandoned country(kruskal+dp树上任意两点距离和)
Problem DescriptionAn abandoned country has n(n≤100000) villages which are numbered from 1 to n. Sin ...
- URAL 1073 Square Country(DP)
题目链接 题意 :这个人要投资地,每块地都是正方形并且边长都是整数,他希望他要买的地尽量的少碎块.每买一块地要付的钱是边长的平方,而且会得到一个一份证书,给你一个钱数,让你求出能得到的证书个数. 思路 ...
- Ural 1073 Square Country (DP)
题目地址:Ural 1073 DP水题.也能够说是背包. #include <iostream> #include <cstdio> #include <string&g ...
- Abandoned country(最小生成树+树形DP)
#include<bits/stdc++.h> using namespace std; struct node{ int u, v, w, nex; bool gone; node(){ ...
- HDU 5723 Abandoned country(最小生成树 + 树形DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5723 [题目大意] n座城市,m条路径,求解: 1.最短的路径和,使得n座城市之间直接或者间接连通 ...
- HDU3466 Proud Merchants[背包DP 条件限制]
Proud Merchants Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) ...
- 浅谈数位DP
在了解数位dp之前,先来看一个问题: 例1.求a~b中不包含49的数的个数. 0 < a.b < 2*10^9 注意到n的数据范围非常大,暴力求解是不可能的,考虑dp,如果直接记录下数字, ...
- UVALive 4987---Evacuation Plan(区间DP)
题目链接 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
随机推荐
- HDU5266 LCA 树链剖分LCA 线段树
HDU5266 LCA Description 给一棵 n 个点的树,Q 个询问 [L,R] : 求点 L , 点 L+1 , 点 L+2 -- 点 R 的 LCA. Input 多组数据. The ...
- C. Painting Fence 分治
memory limit per test 512 megabytes input standard input output standard output Bizon the Champion i ...
- 初识iBatis
在JAVA EE应用程序中,持久层框架常用的有:Hibernate和IBATIS(或MyBatis),Hibernate是全自动的,IBatis是半自动的. IBatis的主要的作用是把SQL语句从我 ...
- SQL Error (2013): Lost connection to MySQL server at 'waiting for initial communication packet', system error: 0 解决方案
远程服务器的操作系统:Ubuntu 本地:navicat +win10 连接名:随意填写 主机名:localhost 端口:3306 用户名:连接电脑的数据库的用户名 密码:连接电脑的数据库的密码 主 ...
- SIGSEGV 和 SIGBUS & gdb看汇编
参考这篇文章: http://blog.chinaunix.net/uid-24599332-id-2122898.html SIGBUS和SIGSEGV也许是我们在平时遇到的次数最多的两个内存错误信 ...
- 【C语言】模拟实现strcmp函数
//模拟实现strcmp函数 //str1>str2,返回1 //str1=str2,返回0 //str1<str2,返回-1 #include <stdio.h> #incl ...
- 深入学习理解java-ThreadLocal
导读 首先,ThreadLocal 不是用来解决共享对象的多线程訪问问题的,普通情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其它线程是不须要訪问的,也訪问不到 ...
- Java基础:初始化和清理
转载请注明出处:jiq•钦's technical Blog (1) 初始化: 所以假设继承关系为:A导出B再导出C,在创建C对象的情况下的调用顺序是: * (1) A的静态域,B的静态域,C的静态域 ...
- sqlite 数据库 相关知识
一基本简单介绍 SQLite 是一个自持的(self-contained).无server的.零配置的.事务型的关系型数据库引擎.由于他非常小,所以也能够作为嵌入式数据库内建在你的应用程序中. SQL ...
- 可设置指定时间自己主动消失的 MessageBox实现
本文主要是讲怎样实现可设置指定时间自己主动消失的 MessageBox提示框ShowMessageBoxTimeout实现: 在开发client应用程序的时候.经经常使用得WinForm中Messag ...