自己原来写的两个维度的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的更多相关文章

  1. 【HDU - 4340】Capturing a country(树形DP)

    BUPT2017 wintertraining(15) #8A 题意 n(<100)个城市组成的树.A攻击i城市需要a[i]代价,B需要b[i].如果一个城市的邻居被A攻击了,那么A攻击它只要A ...

  2. HDU 5723 Abandoned country(kruskal+dp树上任意两点距离和)

    Problem DescriptionAn abandoned country has n(n≤100000) villages which are numbered from 1 to n. Sin ...

  3. URAL 1073 Square Country(DP)

    题目链接 题意 :这个人要投资地,每块地都是正方形并且边长都是整数,他希望他要买的地尽量的少碎块.每买一块地要付的钱是边长的平方,而且会得到一个一份证书,给你一个钱数,让你求出能得到的证书个数. 思路 ...

  4. Ural 1073 Square Country (DP)

    题目地址:Ural 1073 DP水题.也能够说是背包. #include <iostream> #include <cstdio> #include <string&g ...

  5. Abandoned country(最小生成树+树形DP)

    #include<bits/stdc++.h> using namespace std; struct node{ int u, v, w, nex; bool gone; node(){ ...

  6. HDU 5723 Abandoned country(最小生成树 + 树形DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5723 [题目大意] n座城市,m条路径,求解: 1.最短的路径和,使得n座城市之间直接或者间接连通 ...

  7. HDU3466 Proud Merchants[背包DP 条件限制]

    Proud Merchants Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) ...

  8. 浅谈数位DP

    在了解数位dp之前,先来看一个问题: 例1.求a~b中不包含49的数的个数. 0 < a.b < 2*10^9 注意到n的数据范围非常大,暴力求解是不可能的,考虑dp,如果直接记录下数字, ...

  9. UVALive 4987---Evacuation Plan(区间DP)

    题目链接 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

随机推荐

  1. Python 实现批量查询IP并解析为归属地

    一.背景: 最近工作中做了一个小功能,目的是为了分析注册用户区域分布和订单的区域分布情况.所以需要将其对应的IP信息解析为归属地,并同步每天同步更新.线上跑起来效率还是有优化的空间,优化的方向:在调用 ...

  2. Python基础(三) 数据类型

    我们首先要看的是几乎任何语言都具有的数据类型,包括字符串.整型.浮点型以及布尔类型.这些基本数据类型组成了基本控制块,从而创建的Python应用程序. 一.基本结构 1.数值: Python支持不同的 ...

  3. BZOJ 2095 [POI2010]Bridges (最大流、欧拉回路)

    洛谷上有这题,但是输出方案缺SPJ..(而且我也懒得输出方案了) 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2095 题解: 首先判 ...

  4. HDU 1203 背包问题

    题目大意: 根据学校的申请费用,根据已有的钱得到最大的offer率 这里很明显就是一个价值为概率的背包问题 计算两个offer合并的概率 为a + b - a*b #include <cstdi ...

  5. CentOS6网络设置(桥接模式)&Xshell连接虚拟机-

    CentOS无法上网,且Xshell无法连接到虚拟机问题: 目的:在桥接模式下,CentOS能上网,且Xshell能够连接到虚拟机.解决办法:https://www.youtube.com/watch ...

  6. ZooKeeper实现配置中心的实例(原生API实现)(转)

    说明:要实现配置中心的例子,可以选择的SDK有很多,原生自带的SDK也是不错的选择.比如使用I0Itec,Spring Boot集成等. 大型应用通常会按业务拆分成一个个业务子系统,这些大大小小的子应 ...

  7. 【CV论文阅读】Rank Pooling for Action Recognition

    这是期刊论文的版本,不是会议论文的版本.看了论文之后,只能说,太TM聪明了.膜拜~~ 视频的表示方法有很多,一般是把它看作帧的序列.论文提出一种新的方法去表示视频,用ranking function的 ...

  8. 安卓下载文件怎样更新UI进度

    曾经写过几篇关于下载的文章.总的来说是下面几点: 1.维护一个下载进程的Hashmap,key:使用Md5进行处理后的文件下载地址,value为下载的Task. 以防止下载反复.并将信息保存至数据库. ...

  9. CoreData使用方法三: NSPredicate在CoreData中的使用

    NSPredicate在CoreData中经常使用作查询使用,相当于sql语句中的where查询子句. 最经常使用的方法为: NSPredicate *ca = [NSPredicate predic ...

  10. j2se回想

    执行Java程序. Java程序有两种方式一种是jar包.一种是class. 执行jar,Java -jar XXX.jar执行的时候,Java.exe调用GetMainClassName函数,该函数 ...