CodeForces 573D Bear and Cavalry(线段树优化dp)

博客内容概述:解决CodeForces 573D问题,探讨战士和马的交换策略以最大化战士与马之和。通过排序证明每个战士分配的马排名相差不超过2,采用线段树进行优化的动态规划方法。在合并线段树节点时,注意特定情况的处理,如y1=1且x2=0时的特殊情况。提供了AC代码作为解决方案。
摘要由CSDN通过智能技术生成

题意:给出n个战士和他们各自的n批马,我们可以把马换给别的战士,但是都得换(即战士不能拥有原来的马),我们要每个战士乘以给他换的那个马的和最大。q次询问,每次把2个战士的马交换,输出和最大的答案。

做法:把战士根据值排序,我们可以证明每个战士一定不会给他分配排名与他相差超过2的马(可以枚举证明)。首先根据贪心我们可以发觉大的战士分配大的马一定是最好的,但是可能那个战士的排名与马的排名一样导致不能分配,所以如果出现这种情况我们就需要换。而互相换的范围不会超过3,我们可以想象这段排序后的区间是由每段不超过3的区间合并得到的最优值。其实可以直接dp即可,但是复杂度过高,我们可以利用线段树。每个节点维护一个a[i][j]代表左边有i个未被分配,右边有j个未被分配的最大和。合并时讨论中间有多少需要分配即可。

有个需要注意的地方:我们用x1,y1代表左子树,x2,y2代表右子树,如果y1=1,x2 = 0,按理应该是不需要讨论的,因为y1如果要分配只能跟自己分配,而x1,0的值肯定是大于等于(x1,1+最右边自己分配自己(如果可以))。所以当y1 != x2 && y1和x2有个为0就不需要讨论下去了。但是这个其实是不对的,比如,当右子树大小为1时,(x1,1)和(0,1)是可以合并成(x1,2)的。所以当x2 == 0 && x2+y2 == size && y1+y2 < 3的时候是可以合并的,左边也一样。

AC代码:

#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<ctype.h>
#include<algorithm>
#include<iostream>
#includ
引用\[1\]中提到了一种树形动态规划的方法来解决CodeForces - 982C问题。在这个问题中,subtree指的是子连通块,而不是子树。为了使cnt_white - cnt_black尽可能大,可以使用两次树形动态规划来求解。第一次是自底向上的过程,维护一个dp数组,表示以每个节点为根的子树中的最大连通块。第二次是自顶向下的过程,处理自底向上过程中无法包含的树链所代表的子树。在第二次遍历中,需要维护一个sum变量,用于存储树链所代表的子树的贡献。根据ans\[u\]的正负,决定是否能对相邻的子节点做出贡献。如果ans\[u\]为正,则减去dp\[v\]就是树链所代表的子树的权值。最终,ans\[u\]代表包含节点u在内的子连通块的最大权值。\[1\] 问题: CodeForces - 982C 树形DP是什么问题?如何解决? 回答: CodeForces - 982C是一个树形动态规划问题。在这个问题中,需要求解子连通块的最大权值和,使得cnt_white - cnt_black尽可能大。解决这个问题的方法是使用两次树形动态规划。第一次是自底向上的过程,维护一个dp数组,表示以每个节点为根的子树中的最大连通块。第二次是自顶向下的过程,处理自底向上过程中无法包含的树链所代表的子树。在第二次遍历中,需要维护一个sum变量,用于存储树链所代表的子树的贡献。根据ans\[u\]的正负,决定是否能对相邻的子节点做出贡献。最终,ans\[u\]代表包含节点u在内的子连通块的最大权值。\[1\] #### 引用[.reference_title] - *1* *2* [CodeForces - 1324F Maximum White Subtree(树形dp)](https://blog.csdn.net/qq_45458915/article/details/104831678)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值