T1:消失之物
题干:
$ftiasch$ 有 $N$ 个物品, 体积分别是 $W_1, W_2, ..., W_N$。 由于她的疏忽, 第 $i$ 个物品丢失了。 “要使用剩下的 $N - 1$ 物品装满容积为 $x$ 的背包,有几种方法呢?” -- 这是经典的问题了。
她把答案记为 $Count(i, x)$ ,想要得到所有 $1 <= i <= N$, $1 <= x <= M$ 的 $Count(i, x)$ 表格。
输入格式:
第 $1$ 行:两个整数 $N$ $(1 ≤ N ≤ 2 × 10^3)$ 和 $M$ $(1 ≤ M ≤ 2 × 10^3)$,物品的数量和最大的容积。
第 $2$ 行: $N$ 个整数 $W_1, W_2, ..., W_N$ , 物品的体积。
输出格式: 一个 $N × M$ 的矩阵, $Count(i, x)$ 的末位数字
题解:
这道题只需输出个位,有点新奇,但是对算法没什么要求或限制。。。
比较显然就可以得到到一个 $\Theta(n^2x)$ 的一个暴力,就是枚举不要哪一个,再跑一个背包,显然会 $TLE$
正解还是比较难想的。我们其实可以先跑一遍背包(时间复杂度 $\Theta(nm)$),接着想一下怎么更新答案。
题干中要求我们输出的是不选某个物品后装满一个背包的方案数。我们基本上都能想到:先算完所有都可以选的情况,再减去选了某个物品的情况就是答案。我们可以用容斥解决(合法的减去不合法的)。
如果 $j<n$ , 则 $g[i][j]=f[n][j]$;
如果 $j>=n$ ,则 $g[i][j]=f[n][j]-g[i][j-w[i]]$。
我们可以省去第一维:
$\sum\limits_{i=1}^n \sum\limits_{j=v[i]}^{x} g[j] = g[j]-g[j-v[i]]$
($g[i]$ 表示容积为 $i$ 时的方案数,它的初值继承的是所有物品都可以选的情况数;$v[i]$ 为体积)
为什么我们直接减就可以呢?这需要我们想一下背包 $dp$ 的原理:背包 $dp$ 其实相当于不考虑不合法的情况,直接转移,只是在统计答案时将不合法的与不是最优解的情况舍去罢了。这道题的单步容斥就基于此——我们可以用所有情况减去由 $v[i]$ 转移过来的情况就是答案,不需考虑多减或少减的情况,因为这是 $01$ 背包,一个只会算一次贡献,一定不重不漏。
(其实就是全集减去补集)
(注意在更新答案时注意顺序,不要用同级答案相互转移——背包通病)
(在预防同级答案相互转移时并不一定倒序枚举)
Code:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
T2:方伯伯的玉米田
题干:
方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美。
这排玉米一共有 $N$ 株,它们的高度参差不齐。
方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感的玉米拔除掉,使得剩下的玉米的高度构成一个单调不下降序列。
方伯伯可以选择一个区间,把这个区间的玉米全部拔高 $1$ 单位高度,他可以进行最多 $K$ 次这样的操作。拔玉米则可以随意选择一个集合的玉米拔掉。
问能最多剩多少株玉米,来构成一排美丽的玉米。
输入格式:
第 $1$ 行包含 $2$ 个整数 $n$,$K$,分别表示这排玉米的数目以及最多可进行多少次操作。
第 $2$ 行包含n个整数,第 $i$ 个数表示这排玉米,从左到右第 $i$ 株玉米的高度 $a_i$。
输出格式:输出 $1$ 个整数,最多剩下的玉米数。
题解:
这道题有一个小贪心:若在 $x$ 号节点使用操作,让 $n$ 号节点作为右端点一定不劣。
(若右端点不在 $n$ 节点处,而在 $y$ 节点处,那么 y 节点以后的节点相对于拔高的那部分来说是有下降趋势的)
这道题一开始只能想到 $\Theta(n^2k^2)$ 的暴力,交上去才发现一个小测试点也没有。。。
在 $\Theta(n^2k^2)$ 的暴力中,有一个十分显然的 $dp$ 式:(边转移边更新答案)
$\sum\limits_{i=1}^{n}\sum\limits_{j=0}^{k}dp[i][j]=\sum\limits_{l=1}^{i-1}\sum\limits_{r=0}^{j}\max(dp[l][r])+1$
($dp[i][j]$ 表示:转移到第 $i$ 株玉米时、用了 $j$ 次拔高操作后的最长不下降序列的长度)
我们发现在等式右侧,我们找的是一个矩阵的最大值,可以想到用二维树状数组来维护。
(其实 $dp$ 转移方程也可以定义为:转移到第 $i$ 株玉米时、最高高度为 $j$ 的最长不下降序列的长度。但是在实现过程中,$dp[10000][5500] + bit[10000][5500]$ 的数组并不能开下。。。所以用第一种状态——亲测有效)
还有一种 $dp[i][j]$ 转移的定义:用了用了 $i$ 次拔高操作、最大高度为 $j$ 的方案数也可以,实际上就是要保证 $k$ 这一维的存在,当成一个背包来做,其余两维随便一个用树状数组维护一下即可(都是有序的)
Code:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
T3:拦截导弹
题干:
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度、并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高于前一发的高度,其拦截的导弹的飞行速度也不能大于前一发。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
在不能拦截所有的导弹的情况下,我们当然要选择使国家损失最小、也就是拦截导弹的数量最多的方案。但是拦截导弹数量的最多的方案有可能有多个,如果有多个最优方案,那么我们会随机选取一个作为最终的拦截导弹行动蓝图。
我方间谍已经获取了所有敌军导弹的高度和速度,你的任务是计算出在执行上述决策时,每枚导弹被拦截掉的概率。
输入格式:
第一行包含一个正整数 $n$,表示敌军导弹数量;
下面 $n$ 行按顺序给出了敌军所有导弹信息:
第 $i+1$ 行包含 $2$ 个正整数 $h_i$ 和 $v_i$ ,分别表示第 $i$ 枚导弹的高度和速度。
输出格式:
第一行为一个正整数,表示最多能拦截掉的导弹数量;
第二行包含 $n$ 个 $0$ 到 $1$ 之间的实数,第 $i$ 个数字表示第 $i$ 枚导弹被拦截掉的概率(你可以保留任意多位有效数字)。
题解:
一道 $CDQ$ 优化 $dp$ 的题。
三维偏序分别为:$j<i$、$h[j]>=h[i]$、$v[j]>=v[i]$(其中有两维并不是 $>$ 或 $<$,注意一下 $sort$ 时的处理,$sort$ 中尽量不要出现 $>=$ 或 $<=$)
题干中要求输出概率,我们就得记录出它的方案数;又是每一个点的概率,那我们就需要 $dp$ 转移一下:
$f[0][i]$ 数组表示长度为 $i$ 的最长不下降序列长度(以 $1$ 为起点), $f[1][i]$ 数组表示长度为 $i$ 的最长不下降序列长度( $n$ 为起点 )(倒过来),
$g[0][i]$ 数组表示长度为 $i$ 的最长不下降序列长度的方案数,$g[1][i]$ 数组表示长度为 $i$ 的最长不下降序列长度的方案数。
一开始 $CDQ$ 时我们就先以权值优先排序,转移后在用时间排好序
(注意在 $CDQ$ 优化 $dp$ 中,归并排序并不适用)
Code:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
T4:最佳团体
题干:
$JSOI$ 信息学代表队一共有 $m$ 名候选人,这些候选人从 $1$ 到 $n$ 编号。方便起见,$JYY$ 的编号是 $0$ 号。每个候选人都由一位编号比他小的候选人 $R_i$ 推荐。 如果$R_i==0$,则说明这个候选人是 $JYY$ 自己看上的。
为了保证团队的和谐,$JYY$ 需要保证,如果招募了候选人 $i$ ,那么候选人 $R_i$ 也一定需要在团队中。当然了,$JYY$ 自己总是在团队里的。每一个候选人都有一个战斗值 $P_i$,也有一个招募费用 $S_i$ 。$JYY$ 希望招募 $k$ 个候选人($JYY$ 自己不算),组成一个性价比最高的团队。也就是,这 $k$ 个被 $JYY$ 选择的候选人的总战斗值与总招募费用的比值最大。
输入格式:输入一行包含两个正整数 $k$ 和 $n$。接下来 $n$ 行,其中第 $i$ 行包含三个整数 $S_i$、$P_i$、$R_i$表示候选人 $i$ 的招募费用,战斗值和推荐人编号。
输出格式:输出一行一个实数,表示最佳比值。答案保留三位小数。
题解:
这道题要求输出最佳比值,不由想到了 $0/1$ 分数规划,我们先把式子列出来:
$ans=\frac{\sum\limits_{i=1}^n P_i*x_i}{\sum\limits_{i=1}^n S_i*x_i}$
($x_i$ 表示是否选 $i$ 这个人)($x_i$ 为 $0$ 或 $1$)
我们可以移下项:
$\sum\limits_{i=1}^n (P_i-ans*S_i)*x_i=0$
我们就可以发现,若左式不为负,那就是说 ans 满足这个式子;否则就不满足。(这符合决策单调性——二分答案)
用树归搞一搞就可以了:
$dp[x][i+j]=\max(dp[x][i+j],dp[x][i]+dp[to][j])+P_i-ans*S_i$
时间复杂度 $\Theta(n^2log_2ans)$
Code:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
T1:
题干:
题解:
Code:
T1:
题干:
题解:
Code: