动态规划
Aurora141592
这个作者很懒,什么都没留下…
展开
-
洛谷NOIP提高组训练吊打记录(动态规划)
没错,是我被吊打。洛谷 – P1970 – 花匠(递推dp)https://www.luogu.org/fe/problem/P1970被NOIP普及难度的dp吊打?我咋那么菜?int a[maxn], dp[maxn], dp2[maxn];//dp:波峰,dp2:波谷int main(){ ios::sync_with_stdio(0); cin.tie(0); int n; cin >> n; for (int i = 1; i <= n;原创 2021-01-14 12:34:48 · 181 阅读 · 0 评论 -
HDU – 1087 – Super Jumping! Jumping! Jumping!(最大上升子序列)
https://cn.vjudge.net/contest/310994#problem/E这个dp就很经典了。#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 1e3 + 5, mod = 1e9 + 7;int a[maxn], dp[maxn];//dp[i]表示以i结尾的最大值int main(){ ios::sync_with_stdio(0); ci原创 2021-01-14 12:33:39 · 123 阅读 · 0 评论 -
ABC132 – F – Small Products(dp)
https://atcoder.jp/contests/abc132/tasks/abc132_f这道题还是有点想不清楚,以后再来看。#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 1e5 + 5, mod = 1e9 + 7;//dp[i][j]:假设第i位的数是x,则dp[i][j]表示所有使得n / x <= sr[j]的x的答案之和//j的取值的个数是s原创 2021-01-14 12:33:09 · 400 阅读 · 1 评论 -
Comet OJ – Contest #6 – B – 双倍快乐(多进程dp)
https://www.cometoj.com/contest/48/problem/B?problem_id=2278同时进行两个互不干涉的dp并将两个dp的结果合并起来,可以解决很多经典的dp问题。#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 5e2 + 5, inf = 0x3f3f3f3f;int a[maxn], dp[maxn][maxn];//dp[i原创 2021-01-14 12:31:39 · 93 阅读 · 0 评论 -
NOWCODER – 小G砍树(组合数学 + 换根dp)
https://ac.nowcoder.com/acm/problem/22732终于把这题补了。。首先是组合数学的部分,设dp[i]表示以i为根的树的答案(合法排列数),对于根节点为x的树来说,这棵树的所有子节点可以形成((size_x – 1)!)种排列,假设节点y与节点x直接相连,则节点y能形成(size_y!)种排列,但是其中只有dp[y]种是合法的,所以((size_x – 1)!)需要先除掉(size_y!),再乘上dp[y],才是以y为根的子树对dp[x]的真正贡献。dp[i]更新方向为自原创 2021-01-14 12:29:15 · 100 阅读 · 0 评论 -
[动态规划]高维前缀和
求x二进制下的超集或子集的所有状态之和怎么办?那么就要用到高位前缀和了。它通过类似状压dp的方法,通过从低位到高位依次枚举求出所有包含这个位的状态之和,然后向高位转移。枚举超集:for(int j = 0; j < n; ++j){ for (int i = 0; i < (1 << n); ++i){ if (!(i & (1 << j))) f[i] += f[i | (1 << j)]; }}枚举超集原创 2021-01-13 21:19:11 · 390 阅读 · 0 评论 -
[HAOI2008]硬币购物(dp预处理 + 容斥原理 + 思维)
https://www.luogu.org/problemnew/show/P1450硬币购物一共有4种硬币。面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买si的价值的东西。请问每次有多少种付款方法。先dp预处理出假设每种硬币有无限个买价值为i的东西的硬币的方案数(完全背包),然后就有两个很思维的东西了。首先,因为硬币数量有限,根据容斥原理,只要把无限的方案减去第一种硬币超过限制的方案、减去第二种硬币超过限制的方案,减去第三种硬币超过限制的方案、减去第四种硬原创 2021-01-13 21:10:51 · 226 阅读 · 0 评论 -
NOWCODER – 肥猪(dp)
https://ac.nowcoder.com/acm/contest/332/H#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 2e5 + 5, inf = 0x3f3f3f3f;const ll INF = 0x3f3f3f3f3f3f3f3f;int a[2005], b[2005];int main(){ ios::sync_with_stdio(0)原创 2021-01-09 09:43:48 · 97 阅读 · 1 评论 -
[动态规划]四边形不等式优化dp
http://www.51nod.com/Challenge/Problem.html#!#problemId=1022用来优化形如 dp[i][j] = min{dp[i][k] + dp[k + 1][j] + cost[i][j]} 的dp,可以降低n倍复杂度。是否能用四边形不等式优化需要证明:证明cost为凸、证明dp为凸、证明决策单调。但是有个更简单的方法判断是否能使用,那就是写出需要优化的暴力dp程序,输出s的表,看是否满足行列单调,满足就可以四边形不等式优化。const int maxn原创 2021-01-08 13:54:26 · 338 阅读 · 0 评论 -
51nod – 最大M子段和(动态规划)
https://www.51nod.com/Challenge/Problem.html#!#problemId=1052一道神奇的dp题,留着以后分析一下。思考一下动态规划的优化(dp套dp)、初始化、消维和滚动数组。const int maxn = 5e3 + 5;ll sum[maxn], dp[2][maxn], f[2][maxn];int main(){ int n, m; cin >> n >> m; for (int i = 1;原创 2021-01-08 13:48:13 · 101 阅读 · 0 评论 -
[动态规划]数位dp(记忆化dfs版)
保存个模板#include<stdio.h>#include<string.h>using namespace std;typedef long long ll;int a[20];ll dp[20][2];ll dfs(int pos,bool six,bool limit){ if(pos==0) return six?1:0; int state=six?1:0; if(!limit&&dp[pos][state]!=-1原创 2021-01-06 21:11:02 · 102 阅读 · 0 评论 -
[动态规划]CF – 1005 – D. Polycarp and Div 3
http://codeforces.com/contest/1005/problem/D定义ans[i]为前缀长度为i的答案,ans[0] = 0,定义f[i]为前缀和模3的最大前缀长度。那么如何由ans[i – 1]得到ans[i],我们可以只看前缀长度为i的最后一个字符,就是s[i – 1],对于这个字符有两种选择,1是放弃,即ans[i] = ans[i – 1],2是找到前一个前缀和模3相等的最大长度,然后这两个位置之间的部分就相当于一个3的倍数的区间,所以ans[i] = ans[f[sum原创 2021-01-05 13:20:12 · 83 阅读 · 0 评论 -
CF – gym – 101502 – J. Boxes Game(博弈dp + 记忆化搜索 + 思维)
http://codeforces.com/gym/101502/problem/Jdfs居然两行就能写完?恐怖。定义dfs(l, r)返回区间[l, r]的答案, 先看第一次调用这个函数,这个函数返回max(a[l] – dfs(l + 1, r), a[r] – dfs(l, r – 1)),逗号前面是选择左端点,选择左端点之后dfs(l + 1, r)就是区间[l + 1, r]的答案,由于是x – y,所以第一个人先手选择左端点或右端点,后手取剩余区间最大值,两者相减,取其最大值,之后两个人交换原创 2021-01-04 10:45:16 · 209 阅读 · 0 评论 -
CF – 1042 – B. Vitamins(思维 + 状压 + dp)
http://codeforces.com/contest/1042/problem/B#include<bits/stdc++.h>using namespace std;typedef long long ll;inline ll in(){ ll res=0,p=1; char c=getchar(); while(c<'0'||c>'9') {if(c=='-') p=-1; c=getchar();} while(c>='0'原创 2021-01-04 10:33:10 · 117 阅读 · 0 评论 -
[动态规划]编辑距离
https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1183#include<bits/stdc++.h>using namespace std;int dp[1005][1005];int main(){ memset(dp, 0x3f, sizeof(dp)); char a[1005], b[1005]; scanf("%s %s", a + 1, b + 1); int l原创 2021-01-03 14:42:47 · 80 阅读 · 1 评论 -
[算法]LCS及输出LCS
最长公共子序列https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1006#include<bits/stdc++.h>using namespace std;typedef long long ll;char a[1005], b[1005];//pos[i][j]的三个值1,2,3分别表示左、左上和上//pos记录当前LCS是从哪个点过来的,如果不等于2说明当前值是继承自上一个相等的点//所以如果不等于原创 2020-12-31 09:56:19 · 433 阅读 · 0 评论 -
[算法]LIS && LDS(严格和非严格)
LIS#include<bits/stdc++.h>using namespace std;int dp[100005];int main(){ int n, x; cin >> n; memset(dp, 0x3f, sizeof(dp)); for (int i = 0; i < n; ++i){ cin >> x; *lower_bound(dp, dp + n, x) = x;原创 2020-12-30 13:06:06 · 302 阅读 · 0 评论 -
[动态规划]动态规划的优化
目前知道四种方法:单调队列优化,树状数组优化,四边形不等式优化,dp套dp优化。有时间来个总结。还有啥决策单调性啊,保存最优值啊。还有改变dp对象啊。原创 2020-12-29 13:58:15 · 153 阅读 · 0 评论 -
[动态规划]区间型dp
区间型dp:for (int i = 1; i <= n; ++i) scanf("%d", &w[i]);for (int l = 1; l < n; ++l){//枚举区间长度,隔板在右。 for (int i = 1; i + l <= n; ++i){//枚举区间起点,满足i + l <= n //区间右端点直接就是i + l int j = i + l; dp[i][j] = 0x3f3f3f3f;//初始原创 2020-12-29 13:57:40 · 100 阅读 · 0 评论 -
第二届全国高校绿色计算大赛 预赛第二阶段(C++)第2关 运输成本(tarjan求强连通分量 + 缩点 + 拓扑排序 + dp)
https://www.educoder.net/shixuns/g3ep48lh/challenges首先用tarjan求出所有的强连通分量,然后把强连通分量缩点,具体的做法是,把强连通分量内部的点之间的边删掉,只留两两强连通分量之间的边,重新建图,之后这个图就是一个有向无环图,拓扑排序之后dp求最长路就好了。顺便保存个tarjan的模板。#ifndef __SOLVER_H__#define __SOLVER_H__#include <bits/stdc++.h>using n原创 2020-11-04 21:34:02 · 512 阅读 · 0 评论 -
final – 概率期望
http://codeforces.com/gym/101606#include<stdio.h>double dp[405][405];int main(){ int n,k; scanf("%d%d",&n,&k); //dp[i][j]翻i次j个朝上的概率 //翻i次最多只有min(i, n)个朝上 //当朝上的已经等于n了,再翻就是选一个朝上的翻了 dp[0][0]=1; for (int i=1;i<原创 2020-11-04 21:23:14 · 53 阅读 · 0 评论 -
NOWCODER – 小G砍树(组合数学 + 换根dp)
https://ac.nowcoder.com/acm/problem/22732终于把这题补了。。首先是组合数学的部分,设dp[i]表示以i为根的树的答案(合法排列数),对于根节点为x的树来说,这棵树的所有子节点可以形成((size_x – 1)!)种排列,假设节点y与节点x直接相连,则节点y能形成(size_y!)种排列,但是其中只有dp[y]种是合法的,所以((size_x – 1)!)需要先除掉(size_y!),再乘上dp[y],才是以y为根的子树对dp[x]的真正贡献。dp[i]更新方向为自原创 2020-11-04 21:23:51 · 92 阅读 · 0 评论 -
[动态规划]树形dp
https://ac.nowcoder.com/acm/problem/22732终于把这题补了。。首先是组合数学的部分,设dp[i]表示以i为根的树的答案(合法排列数),对于根节点为x的树来说,这棵树的所有子节点可以形成((size_x – 1)!)种排列,假设节点y与节点x直接相连,则节点y能形成(size_y!)种排列,但是其中只有dp[y]种是合法的,所以((size_x – 1)!)需要先除掉(size_y!),再乘上dp[y],才是以y为根的子树对dp[x]的真正贡献。dp[i]更新方向为自原创 2020-11-04 21:26:10 · 63 阅读 · 0 评论 -
HDU – 4713 – Permutation(数论 + 完全背包)
????/acm.hdu.edu.cn/showproblem.php?pid=4713构造任意个数使得它们的和等于n并且它们的积最大。#include<vector>#include<queue>#include<stdio.h>#include<map>#include<set>#include<string.h>#include<algorithm>#include<iostream>#原创 2020-07-04 16:34:47 · 282 阅读 · 0 评论 -
51nod – 1294 修改数组(思维 + dp)
????/.51nod.com/Challenge/Problem.html#problemId=1294给出一个整数数组A,你可以将任何一个数修改为任意一个正整数,最终使得整个数组是严格递增的且均为正整数。问最少需要修改几个数?这题需要把题目转换下,把数组每个数的值减去那个数所在的位置,那些小于0的数一定要修改,剩下的数得到一个新的序列,然后这个序列的最长非降子序列就是最终不需要修改的值。为啥这样是对的呢,因为这样之后需要修改的数一定能修改到一个不会重复的值。int n, cnt = 0;cin原创 2020-07-04 16:31:58 · 357 阅读 · 2 评论 -
51nod 1597 有限背包计数问题
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 1e5 + 5, mod = 23333333;int f[2][maxn];//用了前i个数[1, sqn),和为j的方案数,i维滚动int g[2][maxn];//用了i个数,和为j的方案数。放一个sqn或者全部都加1int h[maxn];//只用大于等于sqn的数,和为i的方案数int pre[maxn];//p原创 2020-05-10 17:48:26 · 209 阅读 · 0 评论 -
51nod 1274 最长递增路径(dp)
题目链接定义dp[i]:走到顶点i的最长路径。为了动态规划的无后效性,得先把边按权值排序。为了不让顶点之间的dp值重复计算,得把上一次的dp值保存下来。由于需要严格递增,所以权值相同的边用到的dp值是一样的,所以可以一次把所有权值相同的边一起加入图里,然后更新答案。dp[u]=max(dp[u],f[v]+1)dp[u] = max(dp[u], f[v] + 1)dp[u]=max(dp[u],f[v]+1)dp[v]=max(dp[v],f[u]+1)dp[v] = max(dp[v], f[u原创 2020-05-09 08:46:07 · 173 阅读 · 0 评论 -
51nod 1259 整数划分 V2(dp)
题目链接#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 5e4 + 5, mod = 1e9 + 7;int f[maxn];//用了前i个数[1, sqn),和为j的方案数int g[2][maxn];//用了i个数,和为j的方案数。放一个sqn或者全部都加1...原创 2020-05-07 21:53:57 · 147 阅读 · 0 评论