1421 秋静叶&秋穣子

 
题目描述 Description

在幻想乡,秋姐妹是掌管秋天的神明,作为红叶之神的姐姐静叶和作为丰收之神的妹妹穰子。如果把红叶和果实联系在一 起,自然会想到烤红薯。烤红薯需要很多的叶子,才能把红薯烤得很香,所以秋姐妹决定比比谁能够收集到最多的红叶。静叶将红叶分成了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+博弈)的更多相关文章

  1. [Codevs 1421]秋静叶&秋穣子(最大-最小博弈)

    题目:http://codevs.cn/problem/1421/ 分析:有向树上的最大-最小博弈 先手与后手的策略不同: 先手A:让对方取得尽量少的前提下,自己取得尽量大 后手B:让自己取得尽量多的 ...

  2. HDU 4532 湫秋系列故事——安排座位 (组合+DP)

    湫秋系列故事——安排座位 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)To ...

  3. [转]Oracle查询树形数据的叶节点和子节点

    oracle 9i判断是叶子或根节点,是比较麻烦的一件事情,SQL演示脚本如下: --表结构-- DROP TABLE idb_hierarchical; create TABLE idb_hiera ...

  4. codevs——1576 最长严格上升子序列(序列DP)

     时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 给一个数组a1, a2 ... an,找到最长的上升降子序列 ...

  5. nyoj-0737-石子合并(dp)

    nyoj-0737-石子合并 题意:有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并 ...

  6. 19-格子游戏(hdu2147博弈)

    http://acm.hdu.edu.cn/showproblem.php?pid=2147 kiki's game Time Limit: 5000/1000 MS (Java/Others)    ...

  7. [每日一题2020.06.16] leetcode双周赛T3 5423 找两个和为目标值且不重叠的子数组 DP, 前缀和

    题目链接 给你一个整数数组 arr 和一个整数值 target . 请你在 arr 中找 两个互不重叠的子数组 且它们的和都等于 target .可能会有多种方案,请你返回满足要求的两个子数组长度和的 ...

  8. 【Java】广州三本秋招经历

    前言 只有光头才能变强 离上次发文章已经快两个月时间了,最近一直忙着秋招的事.今天是2018年10月22日,对于互联网行业来说,秋招就基本结束了.我这边的流程也走完了(不再笔试/面试了),所以来写写我 ...

  9. 【CodeVS 1163】访问艺术馆

    http://codevs.cn/submission/2367697/ loli蜜汁(面向高一)树形dp是这道题的改编. 改编后的题目中每个展览厅的有多个不同的画,偷画的时间和画的价值也不同,求最大 ...

随机推荐

  1. Jenkins integration for AngularJS code coverage

    Install Jenkins plugins 'Cobertura' and 'HTML Publisher' 1. add Post-build Actions "Publish HTM ...

  2. 系统设计 - 使用面向 iOS 的本机插件扩展

    本文转自:http://www.cnblogs.com/zhwl/archive/2013/07/26/3217155.html 本文细致探讨了 Xcode(以 iOS 设备为目标)中的 PhoneG ...

  3. MSSQL Server语句

    随机从数据库中取出20条数据:select top 20 * from 表名 order by newid()

  4. 原始的JDBC操作

    -----------------------------根据配置文件---------------------------- package cn.gdpe.jdbc; import java.io ...

  5. 关于boost::function与boost::bind函数的使用心得

    最近开始写一个线程池,期间想用一个通用的函数模板来使得各个线程执行不同的任务,找到了Boost库中的function函数. Boost::function是一个函数包装器,也即一个函数模板,可以用来代 ...

  6. BOM 之 window

    BOM 之 window 对象 在网页中定义的任何一个对象,变量和函数,都以 window 作为其 Global 对象,因此有权访问别的方法和属性    var age = 26;    functi ...

  7. struts.xml文件示范

    <?xml version="1.0" encoding="GBK"?> <!--下面指定Struts2配置文件的DTD信息--> &l ...

  8. React 学习资源分享 菜鸟刚学5天 博客写的不多 不懂写博客的套路

    http://www.ruanyifeng.com/blog/2015/03/react.html 首先个人强烈推荐 阮一峰的React基础 细细过一遍,看得出大师的用心良苦 然后就开始看书般的过ht ...

  9. 【python之旅】python的面向对象

    一.面向过程 VS 面向对象 1.编程范式 编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程,一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,实现一个任务的 ...

  10. python生成随机二进制文件

    import random def genFile(filename,block=1,size=1): f=open(filename,"wb") content="&q ...