zoukankan      html  css  js  c++  java
  • dp 杂题

    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]]$。

      我们可以省去第一维:

    $sumlimits_{i=1}^n sumlimits_{j=v[i]}^{x} g[j] = g[j]-g[j-v[i]]$

      ($g[i]$ 表示容积为 $i$ 时的方案数,它的初值继承的是所有物品都可以选的情况数;$v[i]$ 为体积)

      为什么我们直接减就可以呢?这需要我们想一下背包 $dp$ 的原理:背包 $dp$ 其实相当于不考虑不合法的情况,直接转移,只是在统计答案时将不合法的与不是最优解的情况舍去罢了。这道题的单步容斥就基于此——我们可以用所有情况减去由 $v[i]$ 转移过来的情况就是答案,不需考虑多减或少减的情况,因为这是 $01$ 背包,一个只会算一次贡献,一定不重不漏。

      (其实就是全集减去补集)

      (注意在更新答案时注意顺序,不要用同级答案相互转移——背包通病)

      (在预防同级答案相互转移时并不一定倒序枚举)

    Code:

    View Code

     

    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$ 式:(边转移边更新答案)

    $sumlimits_{i=1}^{n}sumlimits_{j=0}^{k}dp[i][j]=sumlimits_{l=1}^{i-1}sumlimits_{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:

    View Code
    View Code
    View Code

     

    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:

    View Code

     

    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{sumlimits_{i=1}^n P_i*x_i}{sumlimits_{i=1}^n S_i*x_i}$

      ($x_i$ 表示是否选 $i$ 这个人)($x_i$ 为 $0$ 或 $1$)

      我们可以移下项:

    $sumlimits_{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:

    View Code

     

    T1:

    题干:

     

    题解:

     

    Code:

     

     

    T1:

    题干:

     

    题解:

     

    Code:

     

     

    越努力 越幸运
  • 相关阅读:
    MVC<2:路由映射原理2>
    分支限界>0/1背包 小强斋
    分支限界>装载问题 小强斋
    解空间树搜索 及 最优解 小强斋
    算法>NP难度和NP完全的问题 小强斋
    算法>NP难度和NP完全的问题 小强斋
    分支限界>装载问题 小强斋
    分支限界>0/1背包 小强斋
    分支限界>15谜问题 小强斋
    分支限界>15谜问题 小强斋
  • 原文地址:https://www.cnblogs.com/OI-zzyy/p/11272928.html
Copyright © 2011-2022 走看看