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. 《将博客搬至CSDN》的文章

    我的CSDN地址 博客园应该以后会很少来了.

  2. Java file文件的写入和读取及下载

    File文件的写入 一.FileWriter 和BufferedWriter 结合写入文件 FileWriter是字符流写入字符到文件.默认情况下,它会使用新的内容代替文件原有的所有内容,但是,当指定 ...

  3. iOS 正则表达式-判断邮箱、手机号

    判断是否是邮箱 -(BOOL)isValidateEmail:(NSString *)email { NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[ ...

  4. .NET 设计模式之简单工厂模式(二)

    1:建立接口 namespace Factory { public interface IPerson { } } 2:建立Worker.Student来继承IPerson接口 namespace F ...

  5. winform程序中界面的跳转问题

    首先是我们进行窗口间的跳转,尤其注意的是winform程序里面的空间都是中线程安全的.但是注意的是如果你在一个线程中操纵另外的控件,这时候会提示你一个错误,这个错误的解决方法准备单独的在另一篇文章中来 ...

  6. 水题(素数表)NYOJ素数距离

                描述 现在给出你一些数,要求你写出一个程序,输出这些整数相邻最近的素数,并输出其相距长度.如果左右有等距离长度素数,则输出左侧的值及相应距离. 如果输入的整数本身就是素数,则输 ...

  7. DFS的基础训练清单

    HDU 1010  (AC) HDU 1015    (AC) HDU 1016     (AC) HDU 1172   (AC) HDU 1312   (AC) POJ 2362  (AC,1011 ...

  8. php 连接mysql数据库并显示数据 实例 转载

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  9. Less小记

    Less除了在引用的时候link和script有顺序之外,在编译过程中,less中的代码顺序也会造成对样式的重置.

  10. mount 挂载光盘

    mount作用 挂载光盘镜像文件.移动硬盘.U盘以及Windows网络共享和UNIX NFS网络共享 mount [-t vfstype] [-o options] device dir mount ...