Alice and Bob are going on a trip. Alice is a lazy girl who wants to minimize the total travelling distance, while Bob as an active boy wants to maximize it. At the same time, they cannot let the value to be less than a given integer L since that will make them miss too much pleasure, and they cannot let the value to be greater than a given integer R since they don't want to get too exhausted.
The city they are visiting has n spots and the spots are connected
by directed edges. The spots are connected in such a way that they form
a tree and the root will always be at spot 0. They take turns to select
which edge to go. Both of them choose optimally. Bob will go first.

InputThere are multiple test cases. For every test case, the
first line has three integers, n, L and R (1<=n<=500000, 0<=L,
R<=1000000000). The next n-1 lines each has three integers a, b and
c, indicating that there is an edge going from spot a to spot b with
length c (1<=c<=1000). The spots are labeled from 0 to n-1.

There is a blank line after each test case.

Proceed to the end of file.

OutputIf the total distance is not within the range [L, R], print
"Oh, my god!" on a single line. Otherwise, print the most value Bob can
get.Sample Input

3 2 4
0 1 1
0 2 5 7 2 8
0 1 1
0 2 1
1 3 1
1 4 10
2 5 1
2 6 5 7 4 8
0 1 1
0 2 1
1 3 1
1 4 2
2 5 1
2 6 5 4 2 6
0 1 1
1 2 1
1 3 5

Sample Output

Oh, my god!
2
6
2

题意 :给你一棵树,以及树上的边权,两人轮流取走,先走的总是希望总路程最大,后走的人则希望总路程最小,但要求总的范围在(l, r)

思路分析:

  思路比较好想,类似数字三角形,只不过这是在树上,从叶子向上去递推,明确在每层是谁去走,去怎么更新当前的结点,但是我的代码超时了...

待更新

代码示例:

const int maxn = 5e5+5;

void in(int &a)
{
char c;
while ((c = getchar()) == ' ' || c == '\n');
a = c - 48;
while ((c = getchar()) >= '0' && c <= '9')
a = (a << 3) + (a << 1) + c - 48;
}
int n, l, r;
struct node
{
int to, cost; node(int _to=0, int _cost=0):to(_to), cost(_cost){}
};
vector<node>ve[maxn];
int dis[maxn];
int dp[maxn]; void dfs(int x, int fa, int pt){
if (dis[x] > r) {dp[x]=-1; return;}
if (ve[x].size() == 1) dp[x] = 0;
else dp[x] = pt?-1:inf; for(int i = 0; i < ve[x].size(); i++){
int to = ve[x][i].to;
int cost = ve[x][i].cost;
if (to == fa) continue;
dis[to] = dis[x]+cost; dfs(to, x, !pt);
if (dp[to] == -1 || dp[to] == inf) continue;
if (dp[to]+dis[x]+cost >= l && dp[to]+dis[x]+cost <= r){
if (pt == 1) dp[x] = max(dp[x], dp[to]+cost);
else dp[x] = min(dp[x], dp[to]+cost);
}
}
//printf("++++ x = %d ,pt = %d , dis = %d, %d\n", x, pt, dis[x], dp[x]);
} int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int a, b, c; while(~scanf("%d%d%d", &n, &l, &r)){
for(int i = 0; i <= n; i++) ve[i].clear();
for(int i = 1; i < n; i++){
in(a), in(b), in(c);
ve[a].push_back(node(b, c));
ve[b].push_back(node(a, c));
}
//memset(dis, 0, sizeof(dis));
//memset(dp, 0, sizeof(dp));
dfs(0, -1, 1);
//printf("+++ %d \n", dp[0]);
if (dp[0] >= l && dp[0] <= r) printf("%d\n", dp[0]);
else printf("Oh, my god!\n");
}
return 0;
}

徐州一道网络赛题

In a world where ordinary people cannot reach, a boy named "Koutarou" and a girl named "Sena" are playing a video game. The game system of this video game is quite unique: in the process of playing this game, you need to constantly face the choice, each time you choose the game will provide 1−31-31−3 options, the player can only choose one of them. Each option has an effect on a "score" parameter in the game. Some options will increase the score, some options will reduce the score, and some options will change the score to a value multiplied by −1-1−1 .

That is, if there are three options in a selection, the score will be increased by 111, decreased by 111, or multiplied by −1-1−1. The score before the selection is 888. Then selecting option 111 will make the score become 999, and selecting option 222 will make the score 777 and select option 333 to make the score −8-8−8. Note that the score has an upper limit of 100100100 and a lower limit of −100-100−100. If the score is 999999 at this time, an option that makes the score +2+2+2 is selected. After that, the score will change to 100100100 and vice versa .

After all the choices have been made, the score will affect the ending of the game. If the score is greater than or equal to a certain value kkk, it will enter a good ending; if it is less than or equal to a certain value lll, it will enter the bad ending; if both conditions are not satisfied, it will enter the normal ending. Now, Koutarou and Sena want to play the good endings and the bad endings respectively. They refused to give up each other and finally decided to use the "one person to make a choice" way to play the game, Koutarou first choose. Now assume that they all know the initial score, the impact of each option, and the kkk, lll values, and decide to choose in the way that works best for them. (That is, they will try their best to play the ending they want. If it's impossible, they would rather normal ending than the ending their rival wants.)

Koutarou and Sena are playing very happy, but I believe you have seen through the final ending. Now give you the initial score, the kkk value, the lll value, and the effect of each option on the score. Can you answer the final ending of the game?

Input

The first line contains four integers n,m,k,ln,m,k,ln,m,k,l(1≤n≤10001\le n \le 10001≤n≤1000, −100≤m≤100-100 \le m \le 100−100≤m≤100 , −100≤l<k≤100-100 \le l < k \le 100−100≤l<k≤100 ), represents the number of choices, the initial score, the minimum score required to enter a good ending, and the highest score required to enter a bad ending, respectively.

Each of the next nnn lines contains three integers a,b,ca,b,ca,b,c(a≥0a\ge 0a≥0 , b≥0b\ge0b≥0 ,c=0c=0c=0 or c=1c=1c=1),indicates the options that appear in this selection,in which a=0a=0a=0 means there is no option to increase the score in this selection, a>0a>0a>0 means there is an option in this selection to increase the score by aaa ; b=0b=0b=0 means there is no option to decrease the score in this selection, b>0b>0b>0 means there is an option in this selection to decrease the score by bbb; c=0c=0c=0 means there is no option to multiply the score by −1-1−1 in this selection , c=1c=1c=1 means there is exactly an option in this selection to multiply the score by −1-1−1. It is guaranteed that a,b,ca,b,ca,b,c are not equal to 000 at the same time.

Output

One line contains the final ending of the game. If it will enter a good ending,print "Good Ending"(without quotes); if it will enter a bad ending,print "Bad Ending"(without quotes);otherwise print "Normal Ending"(without quotes).

样例输入1

3 -8 5 -5
3 1 1
2 0 1
0 2 1

样例输出1

Good Ending

样例输入2

3 0 10 3
0 0 1
0 10 1
0 2 1

样例输出2

Bad Ending

题意 : 给你 n 组操作,一个初始分数 m , 以及一个区间,最终分数大于区间右端点输出 good ,小于区间左端点输出 bad ,否则输出 normal , 其实就是两个人在做游戏,每个人每次有三种操作可选,+a , -b, *-1 ,
  先走的人希望最后的分数最大,后走的人希望最后的分数越小,问你最终的情况?
思路分析 : 其实和上面的题目很类似,就是两个人轮流操作,对抗博弈,倒着推一遍就可以了,因为分数有负的,我们可以给其均加上 100 即可
    定义 dp[i][j] 表示到第 i 行时,当前分数为 j 的最优解,
    if (i&1) dp[i][j] = max(dp[i][j], dp[i+1][j+cost]);
    else dp[i][j] = min(dp[i][j], dp[i+1][j+cost]);
代码示例 :
int n, m, k, l;
int arr[1005][3];
int dp[1005][205]; int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout); scanf("%d%d%d%d", &n, &m, &k, &l);
for(int i = 1; i <= n; i++) scanf("%d%d%d", &arr[i][0], &arr[i][1], &arr[i][2]); for(int i = -100; i <= 200; i++) dp[n+1][i+100] = i;
for(int i = n; i >= 1; i--){
if (i&1) {
for(int j = -100; j <= 100; j++){
dp[i][j+100] = -100;
if (arr[i][0]) dp[i][j+100] = max(dp[i][j+100], dp[i+1][min(200, j+arr[i][0]+100)]);
if (arr[i][1]) dp[i][j+100] = max(dp[i][j+100], dp[i+1][max(0, j-arr[i][1]+100)]);
if (arr[i][2]) dp[i][j+100] = max(dp[i][j+100], dp[i+1][-j+100]);
}
}
else {
for(int j = -100; j <= 100; j++){
dp[i][j+100] = 100;
if (arr[i][0]) dp[i][j+100] = min(dp[i][j+100], dp[i+1][min(200, j+arr[i][0]+100)]);
if (arr[i][1]) dp[i][j+100] = min(dp[i][j+100], dp[i+1][max(0, j-arr[i][1]+100)]);
if (arr[i][2]) dp[i][j+100] = min(dp[i][j+100], dp[i+1][-j+100]);
}
}
}
if (dp[1][min(200, m+100)] >= k) printf("Good Ending\n");
else if (dp[1][min(200, m+100)] <= l) printf("Bad Ending\n");
else printf("Normal Ending\n");
return 0;
}

树上对抗搜索 - 树形dp的更多相关文章

  1. BZOJ_4033_[HAOI2015]树上染色_树形DP

    BZOJ_4033_[HAOI2015]树上染色_树形DP Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并 将其他的 ...

  2. 2021.07.17 P3177 树上染色(树形DP)

    2021.07.17 P3177 树上染色(树形DP) [P3177 HAOI2015]树上染色 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.dp思想是需要什么,维护 ...

  3. 树上的等差数列 [树形dp]

    树上的等差数列 题目描述 给定一棵包含 \(N\) 个节点的无根树,节点编号 \(1\to N\) .其中每个节点都具有一个权值,第 \(i\) 个节点的权值是 \(A_i\) . 小 \(Hi\) ...

  4. 【BZOJ4033】[HAOI2015] 树上染色(树形DP)

    点此看题面 大致题意: 给你一棵点数为N的带权树,要你在这棵树中选择K个点染成黑色,并将其他的N-K个点染成白色.要求你求出黑点两两之间的距离加上白点两两之间距离的和的最大值. 树形\(DP\) 这道 ...

  5. 洛谷P3177 [HAOI2015]树上染色(树形dp)

    题目描述 有一棵点数为 N 的树,树边有边权.给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 . 将所有点染色后,你会获得黑点两两之 ...

  6. Codeforces 919 行+列前缀和 树上记忆化搜索(树形DP)

    A B C #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) ...

  7. BZOJ4033: [HAOI2015]树上染色(树形DP)

    4033: [HAOI2015]树上染色 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3461  Solved: 1473[Submit][Stat ...

  8. bzoj 4033: [HAOI2015]树上染色【树形dp】

    准确的说应该叫树上分组背包?并不知道我写的这个叫啥 设计状态f[u][j]为在以点u为根的子树中有j个黑点,转移的时候另开一个数组,不能在原数组更新(因为会用到没更新时候的状态),方程式为g[j+k] ...

  9. BZOJ 4033[HAOI2015] 树上染色(树形DP)

    4033: [HAOI2015]树上染色 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3188  Solved: 1366[Submit][Stat ...

随机推荐

  1. Python--day41--thread1.join()

    在 Python 的多线程编程中,在实例代码中经常有 thread1.join()这样的代码.那么今天咱们用实际代码来解释一下 join 函数的作用. join的原理就是依次检验线程池中的线程是否结束 ...

  2. NuGet 符号服务器

    在新的 VisualStudio 支持使用 NuGet 符号服务器,可以支持新的 Portable PDB 调试符号的库,本文告诉大家如何打包上传带符号的库和使用符号服务器 在 2018 的 11 月 ...

  3. printk函数 用查询来调试

    前面一节描述了 printk 是任何工作的以及怎样使用它. 没有谈到的是它的缺点. 大量使用 printk 能够显著地拖慢系统, 即便你降低 cosole_loglevel 来避免加载控制 台设备, ...

  4. 解决Win10电脑右下角的“激活windows转到电脑设置”的水印的方法

    Win10正式版的用户反馈新系统在使用一段时候后,自己电脑桌面右下角就突然出现了“激活windows10转到设置以激活windows”的水印字样.这是怎么回事呢?下面,我就向大家分享win10电脑右下 ...

  5. Java面向对象程序设计第8章3-5

    Java面向对象程序设计第8章3-5 3.String类型有什么特点? 一旦赋值,便不能更改其指向的字符对象 如果更改,则会指向一个新的字符对象 不能为null 4.String什么时候进行值比较,什 ...

  6. requests爬取梨视频主页所有视频

    爬取梨视频步骤: 1.爬取梨视频主页,获取主页所有的详情页链接 - url: https://www.pearvideo.com/ - 1) 往url发送请求,获取主页的html文本 - 2) 解析并 ...

  7. 【一起学源码-微服务】Nexflix Eureka 源码十:服务下线及实例摘除,一个client下线到底多久才会被其他实例感知?

    前言 前情回顾 上一讲我们讲了 client端向server端发送心跳检查,也是默认每30钟发送一次,server端接收后会更新注册表的一个时间戳属性,然后一次心跳(续约)也就完成了. 本讲目录 这一 ...

  8. SpringCloud + Consul服务注册中心 + gateway网关

    1  启动Consul 2  创建springcloud-consul项目及三个子模块 2.1 数据模块consul-producer 2.2 数据消费模块consul-consumer 2.3 ga ...

  9. AdapterPattern(适配器模式)-----Java/.Net

    适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁.这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能. 这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接 ...

  10. 基于 HTML5 WebGL 与 WebVR 3D 虚实现实的可视化培训系统

    前言 2019 年 VR, AR, XR, 5G, 工业互联网等名词频繁出现在我们的视野中,信息的分享与虚实的结合已经成为大势所趋,5G 是新一代信息通信技术升级的重要方向,工业互联网是制造业转型升级 ...