### 题目链接 ###
分析:
1、用 vector v[i] 来存 i 城堡, s 个对手所安排的士兵数量。
2、设 dp[i][j] 表示 i 城堡前,在当前最大派兵量为 j 时所能获得的最大价值。
3、不难想到的是,遍历 s 个对手,再用两个 for 遍历一下该城堡中各个对手的派兵量。然后对于能派的就派去看看能否更新 dp 值。
4、再者我们考虑贪心思想:若第 i 个城堡中, A 选手派出 a 个兵,那至少需要派 2 * a + 1个兵才能对答案有贡献;再者若 B 选手派出 b 个兵,且 b > a ,那么如果能派出 2 * b + 1 个兵的话,则对于 A 选手那边也可以做出贡献。故我们需要使 v[i] 进行排序,这样 dp 时如果后面大的能满足,那么直接使得 (当前以上的选手数量) * i ,得出当前城堡的贡献即可。
此算法的时间复杂度为 O(nms),看上去达到 2 * 108 ,但在 dp 中会有 break 来剪枝 。
此外由于转移方程中只与上一层即 dp[i - 1][] 有关,故可降到一维。
代码如下:
#define IO freopen("test.in","r",stdin),freopen("test.out","w",stdout)
#define inf 0x3f3f3f3f
#define lson root<<1
#define rson root<<1|1
#include <set>
#include