
线性DP
动态规划---线性DP
(xsj)
模拟只会猜题意
贪心只能过样例
DP一般看规律
数论只会gcd
计算几何瞎暴力
图论只会匈牙利
数据结构没学过
字符串只能干输入
展开
-
牛客小白月赛34 C dd爱科学2.0
题面题解f [i] [j] : 已经处理到了前 i 个字母,第 i 个字母是 j 的最小花费因为这个序列是非递减的,所以前一个不能大于后一个,直接枚举第 i -1 个字母是什么,来转移方程,最小花费就是 s[i] 变到 字母 j+‘A’ 的偏移量代码#include<bits/stdc++.h>using namespace std;const int N = 1e6 + 10;char s[N];int n;int f[N][26];int main()原创 2021-05-29 09:54:42 · 332 阅读 · 2 评论 -
牛客小白月赛34 A dd爱科学1.0
题面题解f [i] [j] : 已经处理到了前 i 个字母,第 i 个字母是 j 的最小花费因为这个序列是非递减的,所以前一个不能大于后一个,直接枚举第 i -1 个字母是什么,来转移方程代码#include<bits/stdc++.h>using namespace std;const int N = 1e6 + 10;char s[N];int n;int f[N][26];int main() { cin >> n >>原创 2021-05-29 09:32:41 · 246 阅读 · 1 评论 -
acwing 3549 最长非递减子序列
题面题解(DP)代码#include<bits/stdc++.h>using namespace std;//111 222 1111 2222int main() { int n; scanf("%d", &n); int s1 = 0, s2 = 0, s3 = 0, s4 = 0; while (n--) { int x; scanf("%d", &x); if (x原创 2021-05-23 08:50:49 · 178 阅读 · 0 评论 -
acwing 1049 大盗阿福
题面题解1 (线性DP)代码1#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;const int N = 1e5 + 10;int t, n;int f[N];int main() { cin >> t; while (t-原创 2021-04-02 19:04:42 · 155 阅读 · 0 评论 -
acwing 272 最长公共上升子序列
题面题解for (int i = 1; i <= n; i ++ ){ for (int j = 1; j <= n; j ++ ) { f[i][j] = f[i - 1][j]; if (a[i] == b[j]) { int maxv = 1; for (int k = 1; k < j; k ++ ) if (a[i] >原创 2021-03-25 17:08:53 · 165 阅读 · 0 评论 -
acwing 187 导弹防御系统 (最长上升子序列)
题面题解拦截导弹的升级版,拦截导弹只让使用不上升子序列,我们就只需要考虑两种情况这道题我们可以使用上升和下降两种序列,那么对于一个数,我们就有4中情况,那么我们就只能dfs暴搜,看这个数放在哪种情况下最优,记得还原状态代码#include<bits/stdc++.h>using namespace std;const int N = 55;int n;int h[N];int up[N]; //不下降序列 (序列种元素的值是递减的)int down原创 2021-03-25 11:23:10 · 321 阅读 · 0 评论 -
acwing 1010 拦截导弹 (最长上升子序列)
题面题解第一问就是最长上升子序列的模型,注意这里求的是最长的不上升子序列第二问: 我们要想序列个数尽可能的少,那么每个序列所放的元素就要尽可能的多,因为要求序列中放的元素不递增,那么对于新加入的元素,我们肯定要放在与这个新元素相差最小且比它大的元素所在队列的后边代码#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<a原创 2021-03-25 09:39:00 · 98 阅读 · 0 评论 -
acwing 1016 最大上升子序列和
题面题解最长上升子序列的另一种形式,之前我们求得是长度,现在求的是最大的和,那么我们就可以把原来的 f[i]=max(f[i],f[j]+1]) 变成 f[i]=max(f[i],f[j]+a[i])代码#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;c原创 2021-03-24 15:05:28 · 83 阅读 · 0 评论 -
acwing 1012 友好城市 (最长上升子序列)
题面题解单调队列二分优化 O(nlogn)代码#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;typedef pair<int, int> PII;const int N = 5010;int n;PII arr[N];int f[N原创 2021-03-24 14:20:49 · 139 阅读 · 0 评论 -
acwing 1017 怪盗基德的滑翔翼 (最长上升子序列)
题面题解最长上升子序列模型,我们只需要从后往前,从前往后分别求一个最长上升子序列,然后取一个最大值即可,这里用的是单调队列二分优化 O(nlogn)代码#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>using namespace std;const int N = 1e5 + 10;int t原创 2021-03-22 21:21:19 · 130 阅读 · 0 评论 -
acwing 1027 方格取数 (数字三角形模型)
题面题解(数字三角形模型)线性DP ,数字三角形模型,摘花生题拓展 ,我们知道,如果是从A到B走一次,那么直接 f[i] [j] = max( f[i-1] [j] , f[i] [j-1] ) + w[i] [j] 考虑坐标为(i,j)的点从上边还是从右边转移过来的最大值即可,但是这个题是要求走两次最大,而且第一次走过的点值会变为0,当然我们也不可以分别求两次,因为两路径最大值相加不一定等于两路径相加的最大值我们可以同时走两条路 f[i1][j1][i2][j2] 就表示所有从(1,原创 2021-03-22 17:58:01 · 166 阅读 · 0 评论 -
acwing 1018 最低通行费 (数字三角形模型)
题面题解线性DP数字三角形模型,题中说最多2n-1个时间,就说明只能是向右和向下到达右下角,不能往回走,摘花生是让求最大,这个是让求最小,求最小我们就要初始化边界代码#include<bits/stdc++.h>using namespace std;const int N = 110;const int INF = 0x3f3f3f3f;int n;int w[N][N];int f[N][N];int main() { cin >>原创 2021-03-22 16:00:29 · 180 阅读 · 0 评论 -
acwing 899 编辑距离 (线性DP)
题面题解最短编辑距离的应用,我们只需要遍历每个字符串,求每个字符串和输入的字符串的最短距离是否小于等于限制,如果符合答案就+1代码#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;const int N = 1100;int n, m;cha原创 2021-03-15 20:52:22 · 157 阅读 · 0 评论 -
acwing 902 最短编辑距离 (线性DP)
题面题解对于两个字符串,我们一般用 f[i][j] 来表示第一个串的前 i 个字母和第二个串的前 j 个字母 ,然后我们划分集合,分三种操作。删除操作 :f[i][j]我们需要删除a字符串的第i ,那么就需要确保a 的第前 i-1 个字母和b的前 j 个字母相同 ,那么转移方程就是 f[i-1][j]+1(操作步骤)增加操作:f[i][j]我们需要增加第 i 字母使得 b的 j-1 和 a 原来的 i 匹配 ,那么转移方程就是 f[i][j-1] +1修改操作 : f[i][j]原创 2021-03-15 20:00:04 · 146 阅读 · 0 评论 -
acwing 896 最长上升子序列II (二分单调优化)
题面题解对于未优化的最长上升子序列问题,我们用 f[i] 来表示以 i 结尾的最长上升子序列 ,然后枚举 i 前面的数,来更新 f[i] 。 这样是 O(n2) 的,此题数据范围大,会超时优化版其实是贪心的思想,对于长度相同的上升子序列, 1 3 5 和 1 2 7 其实我们只需要保留结尾数字小的即可 ,因为结尾越小,我们下一次更新就有可能更多,比如下一个数字是6,那么1 3 5 就可以更新成 1 3 5 6 ,但是 1 2 7 却不可以,所以我们就可以用一个 f 数组 来记录长原创 2021-03-15 11:50:37 · 203 阅读 · 0 评论 -
acwing 897 最长公共子序列
题面题解对于两个字符串,我们就可以用 f[i] [j] 来表示第一个串的前 i 个字母 和 第二串的前 j 个字母代码#include<bits/stdc++.h>using namespace std;const int N = 1100;int n, m;char a[N], b[N];int f[N][N];int main() { cin >> n >> m; cin >> a + 1 &原创 2021-03-14 09:59:20 · 180 阅读 · 0 评论 -
acwing 895 最长上升子序列 (线性DP)
题面题解代码#include<bits/stdc++.h>using namespace std;const int N = 1e3 + 10;int n;int a[N];int f[N];int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); cin >> n; for (int i = 1; i <= n; i++) ci原创 2021-03-13 16:16:32 · 119 阅读 · 0 评论 -
acwing 1015 摘花生 (线性DP)
题面题解代码#include<bits/stdc++.h>using namespace std;const int N = 110;int t, n, m;int w[N][N];int f[N][N];int main() { cin >> t; while (t--) { cin >> n >> m; for (int i = 1; i <= n; i++) {原创 2021-01-29 18:48:06 · 391 阅读 · 0 评论 -
NOIP2004提高组 合唱队形 (最长上升子序列)
原题链接思路1.线性DP中最长上升子序列的变形,我们可以找到最大的 ^ 所组成的人数,然后用n减去这个人数,就是最小出列人数2. 闫式DP分析法,我们设集合a[i]就是以‘^’的最高点,枚举最高点所构成的集合,即可找到最大(a[i]表示以a[i]的值为‘ ^’的顶点所构成的最长子序列)3.如何求每个a[k]我们可以发现,顶点的左右两边是独立的,我们就可以分别求ak左右两边的最大值,然后相加,再减1,(因为ak会被算两次),这样就简单了,两边分别求两个最长上升子序列(一个从前往后,一个从后往原创 2021-01-27 13:07:03 · 174 阅读 · 0 评论 -
cf 846 A Curriculum Vitae (最长上升子序列)
思路由题意得,只有01两个数,0前面不能有1,所以可以转化为求最长上升子序列问题,就是简单dp2.对于i前面的数,只要是不大于arr[i]就可以更新dp[i]AC代码#include<bits/stdc++.h>using namespace std;const int N=110;int n,arr[N],dp[N],ans;int main(){ scanf("%d",&n); for(int i=0;i<n;i++){ .原创 2021-01-05 18:09:37 · 136 阅读 · 0 评论