
动态规划-DP
QingQingDE23
这个作者很懒,什么都没留下…
展开
-
剑指 Offer 49. 丑数
本打算自己写的力扣第一题,结果一道中等题难为了半天,是个动态规划自己一直在走遍历的坑子。原创 2022-10-07 23:47:34 · 200 阅读 · 1 评论 -
AcWing 1053. 修复DNA 题解(状态机DP、AC自动机)
状态机DPS,用ac自动机建立状态机。原创 2022-07-31 16:53:16 · 173 阅读 · 0 评论 -
AcWing 341. 最优贸易 题解 (最短路、dp)
AcWing 341. 最优贸易解题思路:先往dp方面想,将n个点视为n个状态的分界点,dp[k]表示以k为分界点,在k之前买进,在k之后卖出,n个状态会有重复的,但肯定不会有漏掉的(满足dp求最值的条件)。之后怎么求n个状态的dp值就成了关键,因为图可能会存在环,所以不能直接用状态转移dp,依然用spfa最短路径求,不过权值由边转移到了点上,但是道理相同。求两种最短路径,一种是能到达x点的最低的买入价,遍历由ht开头的邻接表记录正向边求得,另一种是求能到达x点的最大的卖出价,遍历由hs记录的逆向邻接表求原创 2022-06-23 18:18:14 · 229 阅读 · 0 评论 -
AcWing 303 运输小猫 题解(动态规划—DP—斜率优化DP)
AcWing 303 运输小猫斜率优化DP应用题,题解借鉴大佬的:大佬题解需要注意的细节是,饲养员数量在外层循环,猫的数量在内层循环,这会影响很大的运算速率#include<bits/stdc++.h>using namespace std;#define int long long const int N = 1e5 + 10, P = 110;int n, m, p;int q[N];int f[P][N]; //表示M只小猫用P位饲养员运输的最小代价int d原创 2022-04-28 21:18:20 · 241 阅读 · 0 评论 -
AcWing 302 任务安排3 题解(动态规划—DP—斜率优化DP)
AcWing 302 任务安排3补充上一题的思路:比上一个任务安排2多了一个t小于0的数据范围,所以直线的斜率可能为负,此时就要对队列内的点值进行二分,找到第一个大于新加入的k的k值,找到合适的k值之后,这个点就是i对应的最小的j值具体题解看这里:如果没有做任务安排1的话建议先做哪个,看第一步题解第一步题解第二步题解#include<bits/stdc++.h>using namespace std;#define int long longconst int N = 3原创 2022-04-26 22:59:55 · 162 阅读 · 0 评论 -
AcWing 301 任务安排2 题解(动态规划—DP—斜率优化DP)
AcWing 301 任务安排2 能被y总设为困难的题果然都不是善茬,思维量很大的一道题,想了好几天,最后终于算是理解了,借鉴一下大佬的题解大佬题解#include<bits/stdc++.h>using namespace std;#define int long longconst int N = 3e5 + 10;int n, S, m;int sc[N], st[N];int q[N];int f[N];signed main(){ cin>&g原创 2022-04-26 12:14:57 · 1063 阅读 · 0 评论 -
AcWing 300 任务安排1 题解(动态规划—DP—斜率优化DP)
AcWing 300 任务安排1解题思路:这题还没上难度,还没有用到斜率优化,将每个任务的时间和花费用前缀和的形式储存,每个任务节点的s都会影响后面的所有节点,所以将这个任务的s的所有影响都算在这一次任务里,用f[i]表示这一批任务结束的任务编号为i,j表示上一批任务的最后一个任务的编号,用前缀和计算公式,求解:公式:f[i] = min(f[i], f[j] + s * (sumc[n] - sumc[j]) + (sumc[i] - sumc[j]) * sumt[i])#include<b原创 2022-04-23 21:15:20 · 974 阅读 · 0 评论 -
AcWing 1091 理想的正方形 题解(单调队列)
AcWing 1091 理想的正方形单调队列应用题,和DP好像没什么关系,借鉴一下大佬写的题解题解原地址#include<bits/stdc++.h>using namespace std;const int N = 1010, INF = 1e9;int n, m, k;int minn[N][N], maxn[N][N];int w[N][N];int q[N];int a[N], b[N], c[N], d[N];int ans = INF;void ge原创 2022-04-22 16:12:28 · 124 阅读 · 0 评论 -
AcWing 1090 绿色通道 题解(动态规划—DP—单调队列优化DP)
思路:单调队列队首内储存从第i题到第i-op-1题中耗时最少的题目,算出做到每一题消耗的最少时间,遍历从n-op到n的最小耗时(这样可以保证最大空题段小于op),如果最小耗时都小于m,那代表这种方案合法,可以降低op的值看更小的空题段能不能满足要求,如果这种方案不合法,那就增大最小空题段的长度(用二分)AcWing 1090 绿色通道#include<bits/stdc++.h>using namespace std;const int N = 5e4 + 10;int n, m原创 2022-04-20 09:25:57 · 197 阅读 · 0 评论 -
AcWing 1089 烽火传递 题解(动态规划—DP—单调队列优化DP)
AcWing 1089 烽火传递单调队列优化DP,思路比较简单,维护一个保持元素单调递增的单调队列,队首就是第i座烽火台能接收到的,代价最小的方案,加上第i座烽火台的代价就是这座烽火台的最小值#include<bits/stdc++.h>using namespace std;const int N = 2e5 + 10;int n, m;int res = 1e9;int w[N];int q[N];int f[N];int main(){ cin>>原创 2022-04-17 11:08:23 · 1141 阅读 · 0 评论 -
AcWing 1087 修剪草坪 题解(动态规划—DP—单调队列优化DP)
推公式的DPAcWing 1087 修剪草坪#include<bits/stdc++.h>using namespace std;#define int long longconst int N = 1e5 + 10;int a[N];int f[N];int s[N];int q[N];int g(int i){ if(!i) return 0; return f[i - 1] - s[i];}int n, m;signed main(){ c原创 2022-04-13 00:12:41 · 781 阅读 · 0 评论 -
AcWing 1214 波动数列 题解(动态规划 蓝桥杯)
原题这题的思路很nb,暂时想不出来#include<bits/stdc++.h>using namespace std;const int N = 1010, mod = 1e8 + 7;int a, b, n, s;int f[N][N];int get(int a, int b){ return (a % b + b) % b;}int main(){ cin>>n>>s>>a>>b; f[0][0] =原创 2022-03-17 18:20:13 · 787 阅读 · 0 评论 -
AcWing 1212 地宫取宝 题解 (动态规划 蓝桥杯)
原题注意多状态的表示和方案数的累加方式#include<bits/stdc++.h>using namespace std;const int N = 55, mod = 1e9 + 7;typedef long long ll;int n, m, k;int w[N][N];//存每个宝贝的价值int f[N][N][13][14];//f[i][j][k][z]表示第i行第j个格子,目前取了k个宝贝,最大价值为z的方案数 int main(){ cin>原创 2022-03-17 13:57:16 · 782 阅读 · 0 评论 -
AcWing 1088 旅行问题 题解(动态规划—DP—单调队列优化DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 2e6 + 10;typedef long long ll;int o[N], d[N];ll q[N], qq[N];bool vis[N];int n;int main(){ scanf("%d", &n); for(int i = 1; i <= n; i ++ ){ scanf("%d%d", &o[i原创 2022-03-03 22:25:57 · 239 阅读 · 0 评论 -
AcWing 135 最大子序和 题解(动态规划—DP—单调队列优化DP)
原题传送门有点类似于前缀和的思想,不过这题如果纯前缀和基本相当于暴力,肯定过不去#include<bits/stdc++.h>using namespace std;const int N = 300010, INF = 1e9;int n, m;int q[N], s[N];int main(){ scanf("%d%d", &n, &m); for(int i = 1; i <= n; i ++ ){ scanf("%d", &am原创 2022-02-28 13:48:43 · 535 阅读 · 0 评论 -
AcWing 1086 恨7不成妻 题解(动态规划—DP—数位DP) (困难)
原题传送门#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N = 19;//long long 的最大值9.22e18const int P = 1e9 + 7;int power7[N + 1];//10^i%7int power10[N + 1];//10^i%Pstruct Node{ int s0, s1, s2;}f[N + 1][10][7][7];i原创 2022-01-22 16:22:49 · 283 阅读 · 0 评论 -
AcWing 1085 不要62 题解 (动态规划—DP—数位DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 35;int n;int f[N][N];//f[i][j]表示i位最高位是j的数字的个数 void init(){ for(int i = 0; i <= 9; i ++ ){ if(i != 4) f[1][i] = 1; } for(int i = 2; i < N; i ++ ){ for(int j = 0; j原创 2022-01-22 11:58:31 · 203 阅读 · 0 评论 -
AcWing 1084 数字游戏 II 题解(实体规划—DP—数位DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 11, M = 110;int P;int f[N][10][M];//f[i][j][k]表示i位数字,最高位为j,mod N 为 k 的数字的个数int mod(int x, int y){ return (x % y + y) % y;} void init(){ memset(f, 0, sizeof(f));//因为有多组测试样例,所原创 2022-01-21 18:05:39 · 2229 阅读 · 0 评论 -
AcWing 1083 Windy数 题解(动态规划—DP—数位DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 11;int f[N][N];//f[i][j]表示i位,最高位为j的数的个数void init() { for (int i = 0; i <= 9; i ++ ) f[1][i] = 1; for (int i = 2; i < N; i ++ ) { for (int j = 0; j <= 9; j ++ ) {原创 2022-01-21 15:51:24 · 259 阅读 · 0 评论 -
AcWing 1082 数字游戏 题解(动态规划—DP—数位DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 15;int a, b, n;int f[N][N];//表示一共有i位,最高位为j的数的个数 void init(){ for(int i = 0; i <= 9; i ++ ) f[1][i] = 1;//将所有一位数字的方案数记录为1 for(int i = 2; i < N; i ++ ){//从二位数字开始遍历 f原创 2022-01-21 14:09:51 · 3786 阅读 · 0 评论 -
AcWing 1081. 度的数量 题解(动态规划—DP—数位DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 35;int X, Y, K, B;int f[N][N];vector<int>V;void init(){ for(int i = 0; i < N; i ++ ){ for(int j = 0; j <= i; j ++ ){ if(!j) f[i][j] = 1;//在i位中选1位的方案数为1 els原创 2022-01-20 12:09:27 · 368 阅读 · 0 评论 -
AcWing 1077 皇宫看守 题解(动态规划—DP—树形DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 1510, INF = 0x3f3f3f3f;int n;int h[N], e[N], ne[N], w[N], idx;bool st[N]; int f[N][3];/*f[i][0]表示i节点能被他的父节点看到的情况下所需要的士兵数 f[i][1]表示i节点能被他的子节点看到的情况下所需要的士兵数 f[i][2]表示i节点有兵的情况下所需原创 2022-01-18 19:12:20 · 287 阅读 · 0 评论 -
AcWing 323 战略游戏 题解(动态规划—DP—树形DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 1510;int n;int e[N], h[N], ne[N], idx;int f[N][2];/*f[i][0]表示第i个节点没有放士兵时,以i为根节点的子树所含的最小士兵数f[i][1]表示第i个节点放士兵时,以i为根节点的子树所含的最小士兵数*/bool st[N]; void add(int a, int b){ e[idx]原创 2022-01-18 18:05:54 · 2440 阅读 · 0 评论 -
AcWing 1074 二叉苹果树 题解 (动态规划—DP—树形DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 110, M = 2 * N;int n, m;int h[N], e[M], ne[M], w[M], idx;int f[N][N];//f[i][j]表示以i为根节点的子树,保留j条树枝能留住的最大苹果数量 void add(int a, int b, int c){ e[idx] =b; w[idx] = c; ne[idx] = h[a原创 2022-01-18 16:45:45 · 125 阅读 · 0 评论 -
AcWing 1075 数字转换 题解(动态规划—DP—树形DP)
原题传送门#include<bits/stdc++.h>using namespace std; const int N = 500010;int n;int ans;int sum[N];int e[N], ne[N], h[N], idx;bool st[N];void add(int a, int b){ e[idx] = b; ne[idx] = h[a]; h[a] = idx ++ ;}int dfs(int u){ int d1 = 0, d原创 2022-01-18 15:52:16 · 227 阅读 · 0 评论 -
AcWing 1073 树的中心 题解(实体规划—DP—树形DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 1e4 + 10, M = 2 * N, INF = 0x3f3f3f3f;int n;int h[N], e[M], ne[M], w[M], idx;int d1[N], d2[N], up[N], p1[N];/*d1[i]记录以i为根节点向下遍历子树找到的最长距离 d2[i]记录以i为根节点向下遍历子树找到的第二长距离 up[i]记录从i向原创 2022-01-18 14:35:29 · 80 阅读 · 0 评论 -
AcWing 1072 树的最长路径 题解 (动态规划—DP—树形DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 1e4 + 10;int e[N], h[N], w[N], ne[N], idx;int n, ans;void add(int a, int b, int c){ e[idx] = b; w[idx] = c; ne[idx] = h[a]; h[a] = idx ++ ;}int dfs(int u, int father){//搜索原创 2022-01-18 11:54:33 · 278 阅读 · 0 评论 -
AcWing 321 棋盘分割 题解(动态规划—DP—区间DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 15, M = 9;const double INF = 1e9;int n, m = 8;int s[M][M];double f[M][M][M][M][N];//f[x1][y1][x2][y2][k]表示在(x1, y1)->(x2, y2)区域内被分成k块的区域的均方差 double X;//平均值 int get_sum(int原创 2022-01-17 15:20:54 · 160 阅读 · 0 评论 -
AcWing 479 加分二叉树 题解(动态规划—DP—区间DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 35;int n;int w[N];int f[N][N], g[N][N];/*f[i][j]记录i到j的最大加分书g[i][j]记录i到j的根节点 */ void dfs(int l, int r){ if(l > r) return ; int k = g[l][r]; cout<<k<<" "; d原创 2022-01-17 13:09:40 · 323 阅读 · 0 评论 -
AcWing 1069 凸多边形的划分 题解 (动态规划—DP—区间DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 55, M = 35;typedef long long ll;int n;int w[N];ll f[N][N][M];//f[i][j]表示两个底角为i、j,顶角在这个区间内的三角形的三端顶点之积的最小值,最后一维M表示这个数用高精度储存,M是这个数的最大位数void add(ll a[], ll b[]){//高精度加法板子 static原创 2022-01-17 11:07:15 · 145 阅读 · 0 评论 -
AcWing 320 能量项链 题解 (动态规划—DP—区间DP)
原题传送门#include<bits/stdc++.h>using namespace std;typedef long long ll; const int N = 210;//将环形视为双链,所以长度因该是题中所给n的两倍 ll n;ll f[N][N];ll w[N];int main(){ cin>>n; for(int i = 1; i <= n; i ++ ){ cin>>w[i]; /* 简化输入,将每一个珠原创 2022-01-16 12:22:02 · 119 阅读 · 0 评论 -
AcWing 1068 环形石子合并 题解 (动态规划—DP—区间DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 410, INF = 0x3f3f3f3f;int n, m;int w[N], s[N];int f[N][N], g[N][N];//f[i][j]记录的是从i到j的区间中合并的最小值,g[i][j]记录的是从i到j的区间中合并的最大值int main(){ /* 将环形区间考虑为双倍长度的链形区间,枚举其中所有长度为n的链,最后求的的最小值/原创 2022-01-16 10:38:38 · 126 阅读 · 0 评论 -
AcWing 524 愤怒的小鸟 题解 (动态规划—DP—状态压缩DP)
原题传送门#include<bits/stdc++.h>using namespace std;#define x first#define y secondtypedef pair<double, double>PDD;const int N = 18, M = 1 << 18;const double eps = 1e-8;int n, m;PDD q[N];//储存每个猪头点的信息int path[N][N];//储存xy点对应的抛物线原创 2022-01-15 19:36:33 · 148 阅读 · 0 评论 -
AcWing 292 炮兵阵地 题解 (动态规划—DP—状态压缩DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 110, M = 1 << 10;int n, m;int g[N];int f[2][N][N];/*利用滚动数组,以为如果三维110数组的话会爆内存f[i][j][k]表示第i行状态为k, 第i - 1行状态为j的状态下已放置的炮台数量 */ int cnt[N];vector<int> state;//记录所有合法原创 2022-01-15 16:59:00 · 153 阅读 · 0 评论 -
AcWing 327 玉米田 题解 (动态规划—DP—状态压缩DP)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 14, M = 1 << 12, mod = 1e8;int n, m;int g[N];//记录每一行的坑vector<int> state; vector<int> head[M];int f[N][M];//表示第N行放置情况为M的方案数 bool check(int state){//判断每列是否合法原创 2022-01-15 15:23:04 · 164 阅读 · 0 评论 -
AcWing 1064 小国王 题解 (动态规划—DP—状态压缩DP)
原题传送门#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N = 12;//因为状态总数为10,但计算结果时利用的是舍弃最后一行求对应的方案数,状态下标从1开始遍历,要用到下标11,所以需要有12个状态下标const int M = 1 << 10;//最大的状态情况const int K = 110;//最多的国王数int n, m;int cnt[M];/原创 2022-01-15 14:06:31 · 279 阅读 · 0 评论 -
AcWing 1052 设计密码 题解 (动态规划—DP—状态机)
原题传送门大佬的题解#include<bits/stdc++.h>using namespace std;const int N = 55, mod = 1e9 + 7;int n, m;char str[N];int nxt[N];int f[N][N];//f[i][j]表示长度为i的字符串,且 int main(){ cin>>n>>str + 1; m = strlen(str + 1); for(int i = 2, j =原创 2022-01-14 17:00:26 · 231 阅读 · 0 评论 -
AcWing 1058 股票买卖 V 题解 (动态规划—DP—状态机问题)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 1e5 + 10, INF = 0x3f3f3f;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][2] = 0; f[0][0] = -INF; f[0]原创 2022-01-14 14:45:07 · 83 阅读 · 0 评论 -
AcWing 1057. 股票买卖 IV 题解 (动态规划—DP—状态机模型)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 1e5 + 10, M = 110;int n, m;int w[N];int f[N][M][2];int main(){ cin>>n>>m; for(int i = 1; i <= n; i ++ ){ cin>>w[i]; } memset(f, -0x3f, sizeof f);/原创 2022-01-14 13:56:55 · 128 阅读 · 0 评论 -
AcWing 1049 大盗阿福 题解 (动态规划—DP—状态机模型)
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 1e5 + 10;int n, T;int w[N];int f[N][2];//f[i][j]表示前i家(及第i家)店铺的状态对应抢的的金额,f[i][0]表示不抢这家店铺,f[i][1]表示抢这家店铺 int main(){ cin>>T; while(T -- ){ cin>>n; f[0][0] = 0原创 2022-01-14 13:10:42 · 122 阅读 · 0 评论