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_ ...
随机推荐
- 51NOD 1287 加农炮(不水的线段树)
>>点击进入原题测试<< Input示例 Output示例 思路:刚开始以为结点存最大值就行了,然后大于左子树的最大值就能进入右子树:然后发现样例都过不了:后面发现,并不是这个 ...
- [luoguP2680] 运输计划(lca + 二分 + 差分)
传送门 暴力做法 50 ~ 60 枚举删边,求最大路径长度的最小值. 其中最大路径长度运用到了lca 我们发现,求lca的过程已经不能优化了,那么看看枚举删边的过程能不能优化. 先把边按照权值排序,然 ...
- hdu2852 KiKi's K-Number
题意:给定三个操作添加删除查询大于a的的第k大值----树状数组的逆向操作 给定a利用BIT查询有多少值比a小,这样比a大的k大值就应该有k+sum(a)个小于他的值 因此可以二分枚举k大值看看是不是 ...
- noip模拟赛 铺瓷砖
[问题描述]有一面很长很长的墙. 你需要在这面墙上贴上两行瓷砖. 你的手头有两种不同尺寸的瓷砖, 你希望用这两种瓷砖各贴一行.瓷砖的长可以用分数表示,贴在第一行的每块瓷砖长度为A/B贴在第二行的每块瓷 ...
- android获取年月日时分秒
Calendar calendar=Calendar.getInstance(); //获取当前时间,作为图标的名字 String year=calendar.get(Calendar.YEAR)+& ...
- Android 学习历程摘要(三)
1.proguard混淆:对与Activity等不应进行混淆.否则系统将找不到生命周期函数:JSON字符串要考虑混淆之后是否会影响字段名:native方法也不混淆,否则调用不到 2.ListView的 ...
- postgresql 创建函数
One of the most powerful features of PostgreSQL is its support for user-defined functions written in ...
- Android从源码看ListView的重用机制
不管是android还是iOS,列表视图应该是最复杂的控件了.android中的listview从命名能够看出是个一维数组,而iOS中的tableview则是二维数组.但事实上须要注意的地方是差点儿相 ...
- duilib-Ex-Debug
因为一些事件google无法訪问,托管在其上的项目也无法检出也基本无人更新,因此维护了一个版本号,用于排除已有的bug和扩展一些功能.这样能够避免反复造轮子和反复的修车子.欢迎大家一起维护.本人能力和 ...
- VFL演示样例
上篇文章向大家介绍了VFL的基本的语法点,假设对下面演示样例不熟的童鞋,能够前去參考.废话不多说.我们直接来看演示样例. 演示样例一 将五个大小同样.颜色不同的view排成一行,view间的间隔为15 ...