codevs 1421 秋静叶&秋穣子(树上DP+博弈)
1421 秋静叶&秋穣子
在幻想乡,秋姐妹是掌管秋天的神明,作为红叶之神的姐姐静叶和作为丰收之神的妹妹穰子。如果把红叶和果实联系在一 起,自然会想到烤红薯。烤红薯需要很多的叶子,才能把红薯烤得很香,所以秋姐妹决定比比谁能够收集到最多的红叶。静叶将红叶分成了N堆(编号1..N), 并且规定了它们的选取顺序,刚好形成一颗有向树。在游戏过程中,两人从根节点开始,轮流取走红叶,当一个人取走节点i的红叶后,另一个人只能从节点i的儿 子节点中选取一个。当取到某个叶子时游戏结束,然后两人会比较自己得到的红叶数量。已知两人采用的策略不一样,静叶考虑在让穰子取得尽可能少的前提下,自 己取的最多;而穰子想得是在自己尽可能取得多的前提下,让静叶取得最少。在两人都采取最优策略的情况下,请你计算出游戏结束时两人的红叶数量。
游戏总是静叶先取,保证只存在一组解。
输入描述
Input Description
第1行:1个正整数N,表示红叶堆数
第2行:N个整数,第i个数表示第i堆红叶的数量num[i]
第3..N+1行:2个正整数u,v,表示节点u为节点v的父亲
输出描述
Output Description
第1行:2个整数,分别表示静叶取到的叶子数和穰子取到的叶子数
样例输入
Sample Input
6
4 16 16 5 3 1
1 2
2 4
1 3
3 5
3 6
样例输出
Sample Output
7 16
数据范围及提示
Data Size & Hint
数据范围
对于30%的数据:1 ≤ N ≤ 100,1 ≤ num[i] ≤ 100
对于60%的数据:1 ≤ N ≤ 10,000,1 ≤ num[i] ≤ 10,000
对于100%的数据:1 ≤ N ≤ 100,000,1 ≤ num[i] ≤ 10,000
提示
样例解释:
首先静叶一定能取得节点1的4片红叶,留给穰子的是节点2和3,均为16片红叶。
若选取节点2则静叶下一次可以最多得到5片红叶,而选择3静叶最多也只能得到3片红叶,
所以此时穰子会选择节点3,故静叶最后得到的红叶数为7,穰子为16。
注意:
保证两人得到的红叶数在[0, 2^31-1]。
【思路】
树上DP+博弈
设f[i][0]表示以i为根的子树先手最优值,f[i][1]相应表示后手最优值。
因为不同的奕者有不同的策略,所以有
当dep为奇[静叶] (设dep[root]=1)
f[i][0]=f[k][1]+num[i]
f[i][1]=f[k][0]
k是i的儿子,且代表f[k][0]取最大时的k,当f[k][0]相同时,取f[k][1]最小。(穰子最优)
当dep为偶时[穰子]
f[i][0]=f[k][1]+num[i]
f[i][1]=f[k][0]
k是i的儿子,且代表f[k][1]取最小时的k,当f[k][1]相同时,取f[k][0]最大。(静叶最优)
【代码】
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
using namespace std; const int N = +;
const int INF = 1e9+1e9; vector<int> G[N];
int n,f[N][],num[N],in[N]; void dfs(int u,int dep) {
int mn=INF,mx=,k=;
if(dep&) {
for(int i=;i<G[u].size();i++) {
int v=G[u][i];
dfs(v,dep+);
if(f[v][]>mx || (f[v][]==mx && f[v][]<mn))
mx=f[v][] , mn=f[v][] , k=v ;
}
f[u][]=f[k][]+num[u];
f[u][]=f[k][];
}
else {
for(int i=;i<G[u].size();i++) {
int v=G[u][i];
dfs(v,dep+);
if(f[v][]<mn || (f[v][]==mn && f[v][]>mx))
mn=f[v][] , mx=f[v][] , k=v ;
}
f[u][]=f[k][]+num[u];
f[u][]=f[k][];
}
}
int read() {
char c=getchar();
while(!isdigit(c)) c=getchar();
int x=;
while(isdigit(c))
x=x*+c-'' , c=getchar();
return x;
}
int main() {
n=read();
for(int i=;i<=n;i++) num[i]=read();
int u,v;
for(int i=;i<n;i++) {
u=read() , v=read();
G[u].push_back(v);
in[v]++;
}
int root;
for(int i=;i<=n;i++)
if(!in[i]) { root=i; break; }
dfs(root,);
printf("%d %d",f[root][],f[root][]);
return ;
}
codevs 1421 秋静叶&秋穣子(树上DP+博弈)的更多相关文章
- [Codevs 1421]秋静叶&秋穣子(最大-最小博弈)
题目:http://codevs.cn/problem/1421/ 分析:有向树上的最大-最小博弈 先手与后手的策略不同: 先手A:让对方取得尽量少的前提下,自己取得尽量大 后手B:让自己取得尽量多的 ...
- HDU 4532 湫秋系列故事——安排座位 (组合+DP)
湫秋系列故事——安排座位 Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)To ...
- [转]Oracle查询树形数据的叶节点和子节点
oracle 9i判断是叶子或根节点,是比较麻烦的一件事情,SQL演示脚本如下: --表结构-- DROP TABLE idb_hierarchical; create TABLE idb_hiera ...
- codevs——1576 最长严格上升子序列(序列DP)
时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 给一个数组a1, a2 ... an,找到最长的上升降子序列 ...
- nyoj-0737-石子合并(dp)
nyoj-0737-石子合并 题意:有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并 ...
- 19-格子游戏(hdu2147博弈)
http://acm.hdu.edu.cn/showproblem.php?pid=2147 kiki's game Time Limit: 5000/1000 MS (Java/Others) ...
- [每日一题2020.06.16] leetcode双周赛T3 5423 找两个和为目标值且不重叠的子数组 DP, 前缀和
题目链接 给你一个整数数组 arr 和一个整数值 target . 请你在 arr 中找 两个互不重叠的子数组 且它们的和都等于 target .可能会有多种方案,请你返回满足要求的两个子数组长度和的 ...
- 【Java】广州三本秋招经历
前言 只有光头才能变强 离上次发文章已经快两个月时间了,最近一直忙着秋招的事.今天是2018年10月22日,对于互联网行业来说,秋招就基本结束了.我这边的流程也走完了(不再笔试/面试了),所以来写写我 ...
- 【CodeVS 1163】访问艺术馆
http://codevs.cn/submission/2367697/ loli蜜汁(面向高一)树形dp是这道题的改编. 改编后的题目中每个展览厅的有多个不同的画,偷画的时间和画的价值也不同,求最大 ...
随机推荐
- Java随机生成定长纯数字或数字字母混合数
(转)Java随机生成定长纯数字或数字字母混合数 运行效果图: 具体实现代码
- Performance tuning library cache lock & single-task message
My colleague suddenly encountered a problem today,a Database becomes very slow , and the a lot of se ...
- 对select into表复制的一点思考
操作系统:Windows 2007 数据库版本:SQL Server 2008 R2 今天写存储过程遇到一个问题,用"Select 1 id,'Boss_he' into A"这样 ...
- Angularjs总结(七) 路由及请求服务等
define(['angular'], function (ng) { 'use strict'; var app = ng.module('index-module', ['ngCookies', ...
- Object-C Init
上一篇为Object-C类实现 我们可以创建一个init方法用来给我们的实例变量设置初始化值: - (id)init { if(self = [super init]) { [self setCapt ...
- iOS SDwebImage 使用说明
SDWebImage托管在github上.https://github.com/rs/SDWebImage 这个类库提供一个UIImageView类别以支持加载来自网络的远程图片.具有缓存管理.异步下 ...
- iOS开发进阶-实现多线程的3种方法
相关文章链接: 1.多线程简介 2.实现多线程的3种方法 ......待续 前言 在多线程简介中,我已经说明过了,为了提高界面的流畅度以及用户体验.我们务必要把耗时的操作放到别的线程中去执行,千万不要 ...
- c#equals相关
1.==是直接比较值类型的值或引用类型的引用地址,但==不能用于struct,struct只能用equals来比较.==一般情况下与object.equals得到的结果是相等的. 2.Referenc ...
- 冒泡排序--c#
//冒泡排序 Console.WriteLine("请输入一个程序的数值"); int[] array = { 111, 2, 5, 32, 321 }; int temp = 0 ...
- Centos6.5安装
前奏:CentOS 6.5下载地址http://mirror.centos.org/centos/6.5/isos/x86_64/CentOS-6.5-x86_64-bin-DVD1to2.torre ...