DP
一些dp的题
(xsj)
模拟只会猜题意
贪心只能过样例
DP一般看规律
数论只会gcd
计算几何瞎暴力
图论只会匈牙利
数据结构没学过
字符串只能干输入
展开
-
acwing 300 任务安排1
题面题解(斜率优化DP)我们将任务从第j个分开,那么j以后的所有任务都要加上一个 s * cf[i] 表示处理完前 i 个物品所用的最小价值,我们以前i 个物品最后分组的位置划分集合,那么就有 f[i] = min(f[j] + (sc[i] - sc[j]) * st[i] + s * (sc[n] - sc[j]));代码#include <cstring>#include <iostream>#include <algorithm>usi原创 2021-04-21 09:10:16 · 75 阅读 · 0 评论 -
acwing 1091 理想的正方形
题面题解(单调队列优化DP)预处理出每一行i以j结尾且长度是k的滑动窗口的最小值和最大值,分别记录在row_min[i][j]和row_max[i][j]位置中在row_min[][] 和 row_max[][]中每一列再用滑动窗口求出最小值和最大值,表示的以i,j结尾且是长度是k的区域的最小值和最大值代码#include <cstring>#include <iostream>#include <algorithm>using namespa原创 2021-04-20 21:58:02 · 90 阅读 · 0 评论 -
acwing 1087 修剪草坪
题面题解(单调队列优化DP)代码#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;typedef long long LL;const int N = 1e5 + 10;LL f[N];LL s[N];int q[N];LL g(int i) { if (i == 0) return 0;原创 2021-04-20 21:10:21 · 113 阅读 · 0 评论 -
acwing 1090 绿色通道
题面题解代码#include<bits/stdc++.h>using namespace std;const int N = 5e4 + 10;const int INF = 1e9;int n, t;int w[N];int q[N];int f[N];bool check(int limit) { int hh = 0, tt = -1; q[++tt] = 0; for (int i = 1; i <= n; i++) {原创 2021-04-20 19:45:17 · 117 阅读 · 0 评论 -
acwing 1089 烽火传递
题面题解(单调队列优化DP)代码#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;const int N = 2e5 + 10;const int INF=0x3f3f3f3f;int n, m;int w[N];int f[N];int q[N];原创 2021-04-20 18:53:31 · 96 阅读 · 0 评论 -
acwing 1088 旅行问题
题面题解(单调队列优化DP)代码原创 2021-04-20 16:48:42 · 112 阅读 · 0 评论 -
力扣 打家劫舍 II
题面题解(状态机模型)对于线性 f[i][0] = max(f[i-1][0],f[i-1][1]) ; f[i][1]=f[i-1][0]+w[i] ,对于环形,我们可以用枚举的方法,我们假设第一个点不选,那么f[0][0] = 0,f[0][1]=-INF(不合法) ,最后的最大值就是max(f[n-1][0],f[n-1][1]) ;假设第一个点选,那么f[0][0]=-INF,f[0][1]=w[0],最后一个点就不能选,最大值只能是f[n-1][0],最后的答案在两者中取最大即可代码原创 2021-04-17 09:33:29 · 76 阅读 · 0 评论 -
acwing 1055. 股票买卖 II
题面题解(状态机模型)f[i][0] : 第 i 天手中没有股票f[i][1] : 第 i 天手中有股票f[0][0] =0 (第0天手中没有股票)f[0][1]= -INF(非法状态,题中让求最大值,所以初始化为最小值)代码#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using names原创 2021-04-17 08:26:01 · 98 阅读 · 0 评论 -
算法竞赛进阶指南---0x12 最大子序和
题面题解代码#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;const int N = 300010, INF = 0x3f3f3f3f;int n, m;int s[N], q[N];int main() { scanf("%d%d", &a原创 2021-02-22 22:34:46 · 86 阅读 · 0 评论 -
acwing 321 棋盘分割
题面题解(记忆化搜索)代码#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int N = 9, M = 15;const int INF = 1e9;int n, m = 8;int s[N][N];原创 2021-04-08 21:12:41 · 80 阅读 · 0 评论 -
acwing 479 加分二叉树
题面题解(区间DP输出方案)我们知道给定一个二叉树的中序遍历,无法确定一颗二叉树,所以就会有很多二叉树状态表示:f[i] [j] 表示中序遍历是 w[i~j] 的的所有二叉树的得分的最大值状态计算:f[l] [r] = max( f[l] [k-1] * f[k+1] [r] + w[k] ) ,即将 f[l] [r] 表示的二叉树集合按根节点分类(分为左根右),则根节点在 k 时的最大得分即为 f[i][k - 1] * f[k + 1][j] + w[k],则f[i][j]即为遍历 k原创 2021-04-08 18:44:27 · 91 阅读 · 0 评论 -
acwing 1069 凸多边形的划分
题面题解我们以六边形为例,假设划分的区间为[l,r] 又因为划分的三角形不能重合,所以我们可以分为三部分,左右和中间,那么 f[l][r] = f[l][k] + f[k][r] + w[l]*w[k]*w[r] ,要想f[l][r]最小,就要使f[l][k]最小+f[k][r]最小,我们只需要枚举[l,r],然后用k划分,更新集合即可由于题中数据范围较大,所以要用高精度,这里直接用java的BigInteger代码import java.math.BigInteger;import原创 2021-04-08 11:24:31 · 126 阅读 · 0 评论 -
acwing 320 能量项链(区间DP)
题面题解输入 2 3 5 10 我们所转换的矩阵就是(2,3) (3,5) (5,10) (10,2) ,合并所用的能量就是矩阵乘法,换种表达方式 2 3 5 10 2 ,长度变为n+1,每次合并就是将三个数中间的数消去,对于环状我们将数组复制一遍变成链状f[l] [r] 将区间 [l,r] 合并的方式的最大值,当然这种方式我们每次是将中间的数消去,所以我们枚举就是枚举中间的数, f[l][r] = max(f[l][r], f[l][k] + f[k][r] + w[l] * w[k]原创 2021-04-07 20:40:12 · 91 阅读 · 0 评论 -
acwing 1068 环形石子合并(区间DP)
题面题解石子合并的扩展版,石子合并是链状的,我们这个题是环状的,只需要将环状转换成链状即可对于环状,我们可以看成图中点,每次合并就是将两个点之间连一条边,最后一次合并一定是将两个链连成一条链,我们就可以发现所有状态其实就是以每个点为结尾断开的情况对于环状我们一般都是将数组复制一遍转化成链状,然后以0-n-1为头节点,长度为n枚举链,就是所有状态代码#include<iostream>#include<cstdio>#include<string原创 2021-04-07 19:53:32 · 98 阅读 · 0 评论 -
acwing 1052 设计密码
题面题解(DP状态机+KMP)KMP匹配过程: 对于模板串我们先提前预处里出ne数组,然后在匹配的时候,如果当前位置的模式串和模板串匹配,那么指针向后移动,如果当前当前位置的模式串和模板串不匹配,我们就要将模板串的指针移动到 ne[j] 的位置继续匹配,当 j 移动到模板串最后的位置(等于模板串的长度),就说明匹配成功,模板串是模式串的字串对于这道题,要设计出只包含小写字母长度位N并且不含子串T的模式串S,那么我们可以先处理T串的ne数组,对于S来说,要想满足条件,那么在匹配的过程中,最终是原创 2021-04-05 10:24:14 · 208 阅读 · 1 评论 -
acwing 1058 股票买卖V
题面题解(状态机)代码#include<bits/stdc++.h>using namespace std;const int N = 1e5 + 10;const int INF = 0x3f3f3f3f;int n;int w[N];int f[N][3];int main() { cin >> n; for (int i = 1; i <= n; i++) cin >> w[i]; f[0][0] = f原创 2021-04-02 22:51:06 · 97 阅读 · 0 评论 -
acwing 1057 股票买卖IV
题面题解代码#include<bits/stdc++.h>using namespace std;const int N = 1e5 + 10, M = 110;const int INF = 0x3f3f3f3f;int n, m;int w[N];int f[N][M][2];int main() { cin >> n >> m; for (int i = 1; i <= n; i++) cin >>原创 2021-04-02 21:28:06 · 104 阅读 · 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 · 126 阅读 · 0 评论 -
acwing 901 滑雪 (记忆化搜索)
题面题解我们可以将 f[i] [j] 集合划分为4个状态,从上下左右四个方向走,就拿向右来说,向右是 f[i] [j-1] 如果可以,那么就是 f[i] [j-1] +1 ( (i,j-1)经过的点再加上 (i,j)这个点);如何求f[i][j-1] 经过的点最多,那么继续往前推即可代码#include<iostream>#include<cstdio>#include<string>#include<cstring>#include&原创 2021-03-20 11:26:45 · 92 阅读 · 0 评论 -
acwing 900 正数划分 (计数类DP)
题面题解1完全背包解法:我们设状态方程为 f[i] [j] 表示 只从 1- i 中选总和是 j 的方案数代码1#include<bits/stdc++.h>using namespace std;const int N = 1100;const int mod = 1e9 + 7;int n;int f[N];int main() { cin >> n; f[0] = 1; ////总和等于0的方案有1种 for (i原创 2021-03-18 09:48:30 · 113 阅读 · 0 评论 -
acwing 282 石子合并 (区间DP)
题面题解我们从小到大枚举合并的区间,以最后一次合并的分界线划分集合,对于区间[l,r] 我们假设最后一次以k划分,那么这次合并最小就等于 f[l][k] +f[k+1][r] +s[r] -s[l+1] (左部分最小+右部分最小+合并这次需要的值) ,有了状态转移方程,我们枚举即可代码#include<iostream>#include<cstdio>#include<string>#include<cstring>#include&l原创 2021-03-15 10:28:11 · 122 阅读 · 0 评论 -
codeforces 1472 C Long Jumps 递推
题面题意题解开始想的的是直接模拟题意,遍历一遍然后求最大,TLE,继续优化,可以加记忆化搜索,把遍历过的标记,还是TLE其实是一个递推,直接从后往前遍历即可代码#include<bits/stdc++.h>using namespace std;const int N = 2e5 + 10;typedef long long ll;ll t, n;ll a[N];ll dp[N];int main() { cin >> t;原创 2021-02-01 10:14:23 · 281 阅读 · 0 评论 -
codeforces 1459 B Move and Turn
原题链接翻译思路首先,我们走i步,可以到达 ceil ( i / 2 ) * 4 个以前从未到达的点,模拟前几个样例即可发现规律然后其他点分奇偶考虑,对于奇数,我们可以用3步代替1步,但是方向会改变,所以奇数还可以到达i-2步的点;对于偶数,我们可以用4步代替0步走,并且没有方向限制,所以偶数还可以到达i-4步的点根据分析我们就可以推出状态转移方程 奇数:dp[i] = dp[i - 2] + 4 * (i + 1) / 2; 偶数 :dp[i] = dp[i - 4] + 4原创 2021-01-25 20:34:19 · 152 阅读 · 0 评论 -
codeforces 1248 C
原题链接Recently Ivan the Fool decided to become smarter and study the probability theory. He thinks that he understands the subject fairly well, and so he began to behave like he already got PhD in that area.To prove his skills, Ivan decided to demonstrate原创 2020-12-19 15:09:13 · 124 阅读 · 1 评论 -
codeforces 1245 C
原题链接Constanze is the smartest girl in her village but she has bad eyesight.One day, she was able to invent an incredible machine! When you pronounce letters, the machine will inscribe them onto a piece of paper. For example, if you pronounce ‘c’, ‘o’, ‘d原创 2020-12-18 16:35:10 · 188 阅读 · 1 评论