
dp
秘制函数
记录学习算法的过程
展开
-
AcWing 487. 金明的预算方案(分组背包)
遍历一组数的可以选择的多种情况,for(int i=0;i++) (k为共有多少数)分组方法:一主多仆情况利用主仆数组,下标为k的仆数组存储主数组编号为k的仆人。原创 2022-10-13 17:02:58 · 331 阅读 · 1 评论 -
AcWing 11. 背包问题求方案数(背包dp)
dp[i][j]:表示从1~i件物品中选,体积恰好为j的最大值。原创 2022-08-15 11:28:12 · 102 阅读 · 0 评论 -
AcWing 1010. 拦截导弹(最长上升子序列dp)
从前往后依次遍历每一个序列中的元素,会有两种选择,如果现有子序列的结尾都小于当前数,则创建一个新序列;要么就把当前数放在结尾小于且最接近当前数的子序列的后面。第二问:贪心(正确性证明:调整法)第一问:经典最长上升子序列问题。...原创 2022-08-04 18:06:07 · 101 阅读 · 0 评论 -
AcWing 1012. 友好城市(最长上升子序列dp)
如果任意两个城市不会发生交叉,那么两座城市在南北两侧的顺序应该是相同的。若给任意一侧的城市按顺序编号,那么要想不出现交叉的现象在另一侧对应城市的编号顺序一定是单调递增或递减的。如此可得,将某一侧城市按顺序编号,只需找到另一侧对应编号的最长上升子序列。...原创 2022-08-02 15:11:48 · 347 阅读 · 0 评论 -
AcWing 275. 传纸条(dp)
思路和方块取数是一样的,唯一不一样的地方是,此题明确规定一个位置只能走一次,经分析可知,方格取数得到的结果肯定可以是两条不相交(无重合路径)的路径,所以方格取数代码也适合本题。............原创 2022-07-31 11:13:15 · 228 阅读 · 0 评论 -
AcWing 1027. 方格取数(线性DP)
思路:两条路径同时出发。状态表示:dp[i1][i2][j1][j2]表示两条路径分别到达两个点的最大值,因为同时走,所以一定会有i1+i2=j1+j2,所以可以简化为三维dp[k][i1][i2],k为路径的横纵坐标之和。状态计算:求某一状态的最大值可以转移成求上一状态的最大值再加上当前所求状态的方格数值,若当前状态的i1和i2相同,那么说明两条路径到达同一位置,因为方格数值不能重复取,所以方格数值只能加一次;若不同,就分别加两个位置的方格数值。上一状态解释:(1.第一条路经从左边来第二条路径原创 2022-05-10 10:23:38 · 263 阅读 · 0 评论 -
acwing.【没有上司的舞会】(树形dp)
#include<iostream>#include<algorithm>#include<cstring>using namespace std;const int N=6010;int happy[N];bool has_father[N];int dp[N][2];int head[N],e[N],ne[N],idx;void add(int x,int y){ e[idx]=y; ne[idx]=head[x]; head[...原创 2022-05-07 10:45:07 · 307 阅读 · 0 评论 -
acwing.选取对数(前缀和+线性dp)
#include<bits/stdc++.h>using namespace std;typedef long long ll;ll dp[5010][5010];ll pre_sum[5010];int main(){ int n,m,k; cin>>n>>m>>k; cin>>pre_sum[1]; for(int i=2;i<=n;i++){ ll t; cin>>t; pre_su...原创 2022-03-21 16:04:32 · 222 阅读 · 0 评论 -
acwing.最短编辑距离(线性dp)
状态表示:dp[i][j]#include<iostream>#include<algorithm>#include<string>using namespace std;int dp[1010][1010];int main(){ int n,m; string a,b; cin>>n; cin>>a; cin>>m; cin>>b; for(原创 2022-03-07 21:56:08 · 249 阅读 · 0 评论 -
acwing.最长公共子序列(线性dp)
状态表示:dp[i][j]表示 字符串a的前i个字符串和字符串b的前j个字符 中最长公共子序列的长度。状态计算:可以分为两种情况,如果a[i]==b[j],那么状态可以转移为dp[i-1][j-1]+1;如果a[i]!=b[j],那么最长公共子序列为max(dp[i-1][j],dp[i][j-1]).#include<iostream>#include<algorithm>using namespace std;int dp[1010][1010];int m原创 2022-03-07 20:53:35 · 212 阅读 · 0 评论 -
acwing.最长上升子序列Ⅱ(贪心)
#include<iostream>#include<vector>#include<algorithm>using namespace std;int main(){ int n; cin>>n; vector<int> arr; for(int i=1;i<=n;i++){ int x; cin>>x; if(arr.empty()...原创 2022-03-07 00:22:15 · 79 阅读 · 0 评论 -
acwing.整数划分(计数类dp)
完全背包解法+优化#include<iostream>#include<algorithm>#include<cstring>#include<vector>using namespace std;const int mod=1e9+7;int dp[1010];int main(){ int n; cin>>n; dp[0]=1; for(int i=1;i<=n;i++){ for(i原创 2022-03-06 16:56:29 · 288 阅读 · 0 评论 -
acwing.【分组背包问题】(背包问题)
其实和01背包差不了多少#include<iostream>#include<algorithm>using namespace std;int wi[110][110],vi[110][110],s[110];int dp[110];int main(){ int n,v; cin>>n>>v; for(int i=1;i<=n;i++){ cin>>s[i]; for(int j=1;j<=s[i]原创 2022-03-05 00:10:36 · 76 阅读 · 0 评论 -
acwing.【多重背包问题Ⅱ】(背包问题)
二进制优化原理:任意一个数都可以以二进制的形式表示出来。例如:第 i 种物品最多有 si 件,每件体积是 vi,价值是 wi。可以把他打包成k件物品,每件物品包含2的k次方件(k=0,1,2....)把所有的物品都以同样的方式打包出来,问题就转化成01背包问题了#include<iostream>#include<algorithm>using namespace std;int wi[25000],vi[25000];int dp[25000];in原创 2022-03-04 23:46:01 · 66 阅读 · 0 评论 -
acwing.【合并石子】(区间dp)
贪心是局部最优解,只能保证局部最优,不能保证全局最优。最后一次合并一定是两堆最小合并代价+所有石子的代价,这两堆是[1,k][k+1,n],k可能是1~n中的任意一个数,假设我们知道k是多少,那么,问题转化成求[1,k]和[k+1,n]的最小合并代价,.......当石子剩余2时,递推回去就可求解了。但是,还有一个问题,去选出k,我们可以遍历当前所求区间每一种k的取值,然后选出最小值。以我目前菜鸡的理解水平,dp就是上述内容倒着看,我们先求出所有递归的结束条件,然后再去求上一层。但是与递归的差别就是原创 2022-02-25 17:01:42 · 1010 阅读 · 0 评论 -
acwing.【滑雪】(记忆化搜索)
dfs+记忆化数组#include<iostream>#include<cstring>using namespace std;int a[310][310];int dp[310][310];int fangx[4][2]={{1,0},{0,1},{-1,0},{0,-1}};int dfs(int i,int j){ if(dp[i][j]!=0){ return dp[i][j]; } int res=0; int k; for(k=0;原创 2022-03-02 18:13:41 · 111 阅读 · 0 评论 -
acwing.【最长上升子序列】(线性dp)
#include<iostream>#include<algorithm>using namespace std;int arr[1010];int dp[1010];int main(){ int n; cin>>n; for(int i=1;i<=n;i++){ cin>>arr[i]; } arr[0]=-2e9; for(int i=1;i<=n;i++){ for(int j=0;j<=i-1;...原创 2022-02-25 18:06:28 · 363 阅读 · 0 评论 -
acwing.【蒙德里安的梦想】(状态压缩dp)
思路:填充长方形的方式就两种,要么就是竖着要么就是横着,假设把所有横着的都排列好,那么竖着的就只能插进去,不会再有其他的不同的填充方案,所以我们只关注横着的或竖着的即可。/*我们先假设对某一列的填充方式为:对第i列填充横着的长方形会伸到第i+1列。在一列中,横着的填充方案数量取决于行数和限制条件,如果不看限制条件,填充一列总共有1<<n种方式(n为行数)如果一列中出现未填充方块 单独或成奇数 存在,到最后就不能填充满,所以一列中不能出现未填充方块 单独或成奇数 存在因为要填充的是横原创 2022-03-01 12:00:21 · 194 阅读 · 0 评论