![](https://img-blog.csdnimg.cn/d7cb8b6984c0489aae99581f3af1ba38.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
动态规划
文章平均质量分 56
分享关于动态规划的知识
MangataTS
一个爱折腾的Coder
展开
-
蓝桥杯每日真题之砝码称重(01背包)
题面来源2021年蓝桥省赛第一场G题题面连接:http://acm.mangata.ltd/p/P1482考点01背包,动态规划视频讲解思路我们定义 f[i][j]f[i][j]f[i][j] 表示的是前 iii 个物品中是否能称出重量为 jjj 的砝码,由于天平是两边都能添加砝码的,于是我们对于右边的来说如果右边的重量大于左边的,我们记为正,反之我们记为负,于是我们对于每一个砝码可以放在左边(权值为负),也可以放在右边(权值为正),也可以不放,那么我们不难得到状态转移:f[i][j]=f[原创 2022-03-24 22:03:26 · 1926 阅读 · 1 评论 -
Codeforces Round #772 (Div. 2) D. Infinite Set (动态规划+思维)
题目链接https://codeforces.com/contest/1635/problem/D题面题意输入一个n表示数组 aaa 的长度,然后输入一个 p,然后输入n个不同的元素,问在 [0,2p][0,2^p][0,2p]范围内有多少数 xxx 满足下列其中至少一种条件,包含满足条件的集合为 SSS :x=aix=a_ix=ai 在数组中x=2×y+1x=2\times y + 1x=2×y+1 并且 yyy 在 SSS 中x=4×yx=4\times yx=4原创 2022-03-03 21:07:44 · 343 阅读 · 1 评论 -
AcWing 901. 滑雪(记忆化搜索)
题目链接https://www.acwing.com/problem/content/903/思路我们定义f[i][j]f[i][j]f[i][j]表示以(i,j)(i,j)(i,j)作为起点的滑行最远距离,由于我们至多只有四个方向滑行且要求只能朝低处滑行,那么我们的状态也最多从四个方向转移过来,于是我们使用搜索在递归的时候处理边界,然后回溯的时候不断地更新f[i][j]f[i][j]f[i][j]地值,详情请看代码代码#include<bits/stdc++.h>using nam原创 2022-02-26 22:25:14 · 307 阅读 · 0 评论 -
AcWing 285. 没有上司的舞会(树形DP)
题面链接https://www.acwing.com/problem/content/description/287/思路对于每一个员工都不希望自己和直接上司参加宴会,那么我们对于当前这个节点就有两种选法选和不选,于是我们定义f[p][0]f[p][0]f[p][0]表示不选p这个点的且以当前点为根的子树选法最大值,f[p][1]f[p][1]f[p][1]表示选p这个点的且以当前点为根的子树选法最大值,假设ppp的子节点集合为VVV那么显然f[p][0]=∑max(f[Vi][0],f[Vi][1]原创 2022-02-26 21:49:04 · 576 阅读 · 0 评论 -
AcWing 91. 最短Hamilton路径(状态压缩DP+哈密顿回路)
题目链接https://www.acwing.com/problem/content/description/93/思路这道题看似像一个最短路,但是并不是,因为我们要求对于每一个点都经过,但是最短路不能保证,所以我们换一个思路用DP,我们定义f[i][j]f[i][j]f[i][j]表示从0走到j,走过的所有点是i状态的最短路径,其中的i我们将其看为二进制表示,对于每一位我们用1表示这一个点走过,用0表示这一个点没走过,那么我们要经过第一个点是0,所以我们初始化f[1][0]=0f[1][0] = 0原创 2022-02-26 17:53:50 · 1076 阅读 · 1 评论 -
AcWing 291. 蒙德里安的梦想(状态压缩DP)
题目链接https://www.acwing.com/problem/content/293/思路我们用一个n位二进制表示一列的情况,那么一列的情况有2n2^n2n种,我们枚举塞1×21\times 21×2的方块数量,那么最后塞入2×12 \times 12×1的方块的数量也是固定了的,我们定义f[i][j]f[i][j]f[i][j]表示已经将前i−1i-1i−1列摆好,且从第i−1i−1i−1列,伸出到第iii列的状态是jjj的所有方案,我们枚举当前第iii列的情况时,我们应该是从i−1i-1i原创 2022-02-24 21:59:52 · 222 阅读 · 0 评论 -
AcWing 338. 计数问题(数位DP)
题目链接https://www.acwing.com/problem/content/340/思路我们想要快速求得[1,n][1,n][1,n]内所有数的某些数字出现的次数,那么我们要从十进制数位出发,我们从左往右或者从右往左枚举每一个数位,对于当前的这个数位我们是已经定了的,所以我们就看当前这个位置的前面和后面分别有多少种枚举的方法,首先无论当前的这一位是否大于我们要计算的位值,我们都会有(l−1)×p(l-1) \times p(l−1)×p的方案数量,如果当前计算的位值不为0的话那么说明还有前缀原创 2022-02-24 15:23:30 · 565 阅读 · 0 评论 -
石子合并简化版(区间DP)
题目链接https://www.acwing.com/problem/content/284/思路因为只能合并相邻的两堆石子,并且首位不构成环,那么我们用f[i][j]f[i][j]f[i][j]表示区间[i,j][i,j][i,j]这个范围的一个合并最小值那么我们思考这个状态怎么转移过来,显然的是肯定是从更加细微的区间转移过来,那么我们就对区间进行一个划分操作,我们将其划分为[i,k][i,k][i,k]和[k+1,j][k+1,j][k+1,j]两部分,然后将这两个区间合并,那么我们只需要枚举一下原创 2022-02-21 17:11:44 · 360 阅读 · 0 评论 -
编辑距离(线性DP+暴力匹配)
题目链接https://www.acwing.com/problem/content/901/思路其实这一道题的思路和上一道题是一样的,只不过我们对于每一次询问需要做n次匹配判断,如果当前的操作次数低于k那么说明我们这个字符串是合法的,关于怎么匹配俩字符串的最低花费次数,我们可以上一篇:最小编辑距离代码#include<bits/stdc++.h>using namespace std;const int N = 1e3+10;int n,m;char a[N][15],b原创 2022-02-21 14:55:21 · 166 阅读 · 0 评论 -
AcWing 902. 最短编辑距离(线性DP)
题目链接https://www.acwing.com/problem/content/description/904/思路因为题目中有三种操作A字符串的方法:删除A中一个元素给A增加任意元素将A中任意位置替换成某个元素我们定义f[i][j]f[i][j]f[i][j]表示的是字符串A从[1,i][1,i][1,i]和字符串B[1,j][1,j][1,j]完成匹配需要的最少操作次数,那么我们考虑最A字符串的最后一个位置的操作情况如果A最后一个位置是删除操作,说明从A字符串中[1,i−1]原创 2022-02-21 11:09:01 · 244 阅读 · 0 评论 -
AcWing 897. 最长公共子序列(LCS朴素版)
题目连接https://www.acwing.com/problem/content/899/思路我们定义f[i][j]f[i][j]f[i][j]表示的是a串中长度为i和b串长度为j的最长公共子序列长度,那么我们当前匹配到的a[i]和b[j]如果相等f[i][j]f[i][j]f[i][j]的值一定是从f[i−1][j−1]f[i-1][j-1]f[i−1][j−1]转移过来的,即f[i][j]=f[i−1][j−1]+1f[i][j]=f[i-1][j-1]+1f[i][j]=f[i−1][j−1原创 2022-02-18 13:29:12 · 265 阅读 · 0 评论 -
AcWing 896. 最长上升子序列 II(二分优化LIS)
题目连接https://www.acwing.com/problem/content/description/898/思路我们用一个f[i]f[i]f[i]表示以长度为i结尾的子序列的最小值的大小,那么不难发现我们这个f数组是一个单调递增的序列,那么我们就能对我们往前匹配的过程做一个二分优化,也就是找到长度尽量大的且比当前a[i]a[i]a[i]值小的一个位置,如果我们发现当前的这个a[i]a[i]a[i]是比之前所有的元素都要大的,那么我们就应该让我们的最长序列的长度增加,并将a[i]a[i]a[i原创 2022-02-18 12:36:53 · 286 阅读 · 2 评论 -
AcWing 895. 最长上升子序列(LIS朴素做法)
题目连接https://www.acwing.com/problem/content/897/思路因为数据范围很小,所以我们定义f[i]f[i]f[i]表示的是以第i个元素结尾的最长上升子序列的长度,那么我们每次从[0,i]扫一遍然后去一个max就好啦代码#include<bits/stdc++.h>using namespace std;const int N = 5e2+10;int a[N][N],f[N][N];int n;int main(){ cin原创 2022-02-17 23:07:20 · 154 阅读 · 0 评论 -
AcWing 898. 数字三角形(线性DP)
题目连接https://www.acwing.com/problem/content/description/900/思路我们知道对于当前的这一层,只能从左上和正上方转移过来,那么我们定义f[i][j]f[i][j]f[i][j]表示的是从第一层到第i层第j列的最大路径数值和,那么不难发现f[i][j]=a[i][j]+max(f[i−1][j−1],f[i−1][j])f[i][j] = a[i][j] + max(f[i-1][j-1],f[i-1][j])f[i][j]=a[i][j]+max(原创 2022-02-17 23:06:29 · 251 阅读 · 0 评论 -
智乃买瓜(another version)(DP+逆向思维)
题目连接https://ac.nowcoder.com/acm/contest/23478/C题面思路我们现在是已经知道每个重量的瓜的个数,出现质量和为奇数是由于我们购买半个瓜的操作那么就可以从小到大逆推,首先能够知道,f[1]f[1]f[1]的值实际上就是质量为2的瓜的数目。然后我们回顾上一题的状态转移方程:f[i][j]=f[i−1][j]+f[i−1][j−a[i]]+f[i−1][j−a[i]∗2]f[i][j] =f[i-1][j] + f[i-1][j-a[i]] + f[i-1原创 2022-02-05 15:29:41 · 295 阅读 · 0 评论 -
智乃买瓜(多重背包)
题目连接https://ac.nowcoder.com/acm/contest/23478/B题面思路我们这里将半块瓜看成一件物品,那么对于每一件物品我们有三种选择方式不选选一个选两个那么我们直接套一个01背包即可状态转移方程为:f[i][j]=f[i−1][j]+f[i−1][j−a[i]]+f[i−1][j−a[i]∗2]f[i][j] =f[i-1][j] + f[i-1][j-a[i]] + f[i-1][j-a[i]*2]f[i][j]=f[i−1][j]+f[i−1][j原创 2022-02-05 14:26:08 · 191 阅读 · 0 评论 -
九小时九个人九扇门(01背包)
题目链接https://ac.nowcoder.com/acm/contest/23106/A题面思路小技巧一个数的数字根就是它对9取模,当然取模得0的数字跟就是9做法我们要求的是从n个人中选一些人,假设这些人的数字用a数组存储,然后将其数字相加,然后求一个数字根,然后将这个数字根的方案数加一,那么这个问题可以转化为01背包问题,因为每一个人的数字只能使用最多一次,也就是每个人的数字存在两种状态:选择or不选择,那么我们定义一个数组f[i][j]表示的是前i个人选中的数字根方案为j的方案数原创 2022-01-27 18:15:51 · 468 阅读 · 0 评论 -
HDU 5586 Sum (预处理 + 动态规划)
题目链接:传送门题意:给你n个数字,然后你可以对这n个数组的任意一个子区间进行一个操作,\(f(x)=(1890x+143)mod10007\),或者不进行操作,问你怎样操作能使得加和最大解题思路:我们通过预处理a数组元素,把改数字操作后的值和操作前的值进行一个做差存储在b数组里面,此时问题便转化为了求解b数组连续的子序列的和的值,当然如果b数组连续子序列和的值小于0,我们就不对a数组的元素...原创 2021-01-20 20:21:00 · 148 阅读 · 1 评论