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_ ...
随机推荐
- Django-REST_Framework 第三方登录
DRF第三方登录,我们将使用第三方包实现!!! 1.首先安装 pip install social-auth-app-django 文档请看 https://python-social-auth.re ...
- flex多列布局遇到的问题,和解决方案
flex布局无疑是简单.易用的,他让我我们的布局更加简单和快速,但是在使用flex进行多列布局的时候,我相信很多人会遇到下面的情况: 这种情况是因为我们使用了justify-content: spac ...
- linux 简单实用小操作
mysql改密码 通过root以后,(root密码忘记就没法了) alter user username@'%' identified by 'password' 端口被占用 sudo fuser - ...
- BNUOJ 33898 Cannon
Cannon Time Limit: 1000ms Memory Limit: 65535KB This problem will be judged on HDU. Original ID: 449 ...
- Android第三方开源SeekBarCompat:音乐类播放器等APP进度条常用
Android第三方开源SeekBarCompat:音乐类播放器等APP进度条常用 Android平台原生的SeekBar设计简单,然而,比如现在流行的一些音乐播放器的播放进度控制条,如果直接使 ...
- COJ 1411 Longest Consecutive Ones
题目大意: 希望在 k 步之内,将尽可能多的1移到相邻的位置上 这里依靠前缀和解决问题 我们用pos[i]保存第i个1的位置,这里位置我以1开始 用sum[i]保存前 i 个1从 0 点移到当前位置所 ...
- 次小生成树 判断 unique MST
Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spann ...
- Java泛型解析(01):认识泛型
Java泛型解析(01):认识泛型 What Java从1.0版本号到如今的8.中间Java5中发生了一个非常重要的变化,那就是泛型机制的引入.Java5引入了泛型,主要还是为了满足在199 ...
- Kafka无法消费!?究竟是bug的“沦陷”还是配置的“扭曲”?
在一个月黑风高的夜晚,突然收到现网生产环境Kafka消息积压的告警,梦中惊醒啊,马上起来排查日志. 问题现象 消费请求卡死在查找Coordinator Coordinator为何物?Coordinat ...
- android 4.0主线程訪问网络问题
在4.0下面,在主线程中訪问网络,假设请求超过6s的话,就会报ANR,那么这就会带来一个问题,假设网络慢或者请求的数据过大时,界面会卡顿,造成界面灵敏性非常差,因此网络请求一般不能放在主线程中操作,g ...