0开始的动态规划
嘤嘤嘤
ddgo
给我高高飞起来啊!(ACM退役,转JAVA后端了)
展开
-
CCF 202109-4(状态压缩 + 期望DP)
配套地址将每一个卡牌是否选取用状压 sss 表示。设 dp(s,j)dp(s,j)dp(s,j) 表示 到达 状态(111....11)(111....11)(111....11) 且 当前硬币数为 j 个还需要选的次数。那么if(s>>z)&1==1:if (s >> z) \& 1 == 1:if(s>>z)&1==1:dp(s,j)=dp(s,j+1)×p(z)dp(s,j) = dp(s,j+1) \times p(z)dp(原创 2021-10-02 23:33:37 · 668 阅读 · 0 评论 -
Tickets (HDU1260)(线性DP)
题目地址配套地址设dp(i,0)dp(i,0)dp(i,0) 表示第 i 个人单独买票,dp(i,1)dp(i,1)dp(i,1) 表示第 i 个人与前面的那个人一起买票。故有转移方程dp(i,0)=min(dp(i−1,0),dp(i−1,1))+s(i)dp(i,0) = min(dp(i-1,0),dp(i-1,1)) + s(i)dp(i,0)=min(dp(i−1,0),dp(i−1,1))+s(i)dp(i,1)=min(dp(i−2,0),dp(i−2,1))+d(i−1)dp(i原创 2021-09-16 18:47:44 · 138 阅读 · 0 评论 -
免费馅饼(HDU1176)(线性DP)
题目地址配套地址时间看成纵坐标,位置看成横坐标,然后就是类似数字金字塔。#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>using namespace std;const int N = 1e5 + 10;const int mod = 998244353;//#define int long longtypedef long long ll;int原创 2021-09-16 17:17:20 · 75 阅读 · 0 评论 -
Doing Homework(HDU1074)(状压DP)
题目地址配套地址设 dp(i)dp(i)dp(i) 表示当前状态为 i 时,得到的最小扣分。枚举最后的作业,来更新当前状态。注意题目给出的是升序,故枚举最后的作业是逆序,最后的作业字典序尽可能的大。#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>using namespace std;const int N = 16;const int mod = 99原创 2021-09-16 16:09:39 · 79 阅读 · 0 评论 -
P5144 蜈蚣 (线性DP)
题目地址配套地址设 dp(i,j)dp(i,j)dp(i,j) 表示前 iii 个点分成前 jjj 段 得到的最大值。转移方程dp(i,j)=dp(k−1,j−1)+xorkidp(i,j) = dp(k-1,j-1) + xor_{k}^{i}dp(i,j)=dp(k−1,j−1)+xorki枚举最后一段的起点,进行转移,注意长度为1单独处理#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<原创 2021-09-11 18:21:09 · 127 阅读 · 0 评论 -
游走(luogu)(期望)
题目地址配套地址答案为sumcnt\frac{sum}{cnt}cntsum sum 为所有路径的总长度,cnt为所有路径的个数。题中信息可以得到,改图形是一个DAG,可以设f(i)表示以i为起点的所有路径的总长度之和,g(i)表示以i为起点的所有路径的个数。那么f(i)=∑j∈s(f(j)+g(j))f(i) = \sum_{j\in{s}}(f(j) + g(j))f(i)=∑j∈s(f(j)+g(j)) ,首先边长为1,对于f(j)中的所有路径,当变成由i为起点时,每个路径都要加1的长原创 2021-06-29 15:26:22 · 194 阅读 · 0 评论 -
单选错位(luogu)(期望)
题目地址配套地址尽管刚开始是完全正确,但是错位了,正确的概率对每题还是一样的。决定概率变化的只有题目的数量不同。每次比较前面一个和后面一个选项个数,每次以大的作为概率计算。#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>using namespace std;const int N = 1e7 + 10;const int mod = 1e9 + 7;原创 2021-06-29 11:43:15 · 160 阅读 · 0 评论 -
绿豆蛙的归宿(luogu)(期望DP)
题目地址配套地址逆向:设E(i) 表示到i点到n点还需要的期望步数仅考虑 x -> y这一条边,边权为w。设 y 点所连的各个点的边权为l1,l2,...,lnl_1,l_2,... ,l_nl1,l2,...,ln,概率为p1,p2,...,pnp_1,p_2,...,p_np1,p2,...,pn那么 E(y) = p1l1+p2l2+...+pnlnp_1l_1 + p_2l_2 + ... + p_nl_np1l1+p2l2+...+pnlnE(x) =原创 2021-06-29 10:58:59 · 186 阅读 · 1 评论 -
低买(acwing)(线性DP)
题目地址配套地址/* 最长下降子序列,求方案数。 预先用n ^ 2 处理完最长下降子序列。 dp(i) 表示前i个构成最长下降子序列 之后用ans(i)表示构成以i结尾的最长下降子序列的方案数, ans(i) += ans(j),且 dp(j) + 1 = dp(i) && a(j) > a(i),j < i 初始化ans数组,为每一段的起点是初始为1. 注意当价格序列相同,只计算一次。原创 2021-06-25 22:50:14 · 105 阅读 · 0 评论 -
花店橱窗(acwing)(线性DP)
题目地址配套地址/* dp(i,j) 表示前i个花瓶放置花,且前i个花瓶放置最大为第j号的花得到的最大值 j == 0 dp(i,0) = dp(i-1,0) else dp(i,j) = max(dp(i-1,j-1) + w[k][i],dp(i-1,j)); 当dp[i-1][j] == dp[i][j] 说明这个花瓶相当于没有被用,因为字典序最小,每次取i值最小。 */#include<bits/stdc++.h>using原创 2021-06-25 16:46:37 · 152 阅读 · 0 评论 -
乌龟棋(acwing)(线性DP)
题目地址配套地址/* dp(i,a,b,c,d) 表示走到i位置时,已经走了a个1,b个2,c个3,d个4的最大得分 那么由前往后推: distance = w[a+b*2+c*3+d*4]; 下一步走的是1,当dp(i,a,b,c,d)被更新 dp(i+1,a+1,b,c,d) = dp(i,a,b,c,d) + w[distance + 1]; 同理。 350 * 30 * 30 * 30 * 30 -> 283500000 O(2e8)原创 2021-06-25 14:44:34 · 213 阅读 · 0 评论 -
三阳开泰 (nowcoder)(数位DP)
题目地址配套地址看数据范围,贼像数位DP,但是平时都是写的只有一个数字限制的数位DP,数字变成了三个,那就在dfs里面开一个for循环3重枚举。将十进制全部转为二进制,进行每位的枚举。这也是方便每一位进行异或处理之后的判断。从高位往低位思考,如果当前枚举的这位数字两两异或大于x的这一位,并且这两个数的异或有限制,那么就不满足题目的第二个条件。这个 “有限制” 等同于枚举数字时的限制。记得pos等于每个数二进制最长的,这里直接从70位开始。代码#define IOS ios::sync_wit原创 2021-05-27 20:15:58 · 424 阅读 · 0 评论 -
炮兵阵地 (AcWing292)(状压DP)
题目地址配套地址以行为突破口,先预处理每行的合法状态(每两个1之间必须大于等于两个0),然后将图中的每一行状态表示出来,用于判断这个状态是否能放置到当前行。转移必须与前两行有关。设dp(i,j,k)dp(i,j,k)dp(i,j,k)表示当前行的状态为j,上一行的状态为k,那必须k与j = 0 并且 i与j = 0 并且 i与k == 0才能转移,并且当前行选的状态能够放到当前行(因为有H),注意空间,可以用滚动数组优化。代码#define IOS ios::sync_with_stdio(fa原创 2021-05-27 17:58:28 · 173 阅读 · 1 评论 -
WZB‘s Harem(nowcoder)(状压DP)
题目地址配套地址每一行对应一个二进制的状态,1表示皇后放在那里。以行为状态转移突破口,用dp(i,j)表示,前i行且总的选择的状态为j时,安排皇后的方案。最后答案 dp(n−1,(1<<n)−1)∗n!dp(n-1,(1 << n) - 1) * n!dp(n−1,(1<<n)−1)∗n! 注意要乘一个全排列。每一个行放置皇后的合法状态对应的状态仅包含一个1。当前行的这个状态中的1不能与输入数组中的当前行当前列的1同时出现。处理完标记到vaid(i原创 2021-05-21 20:12:22 · 137 阅读 · 0 评论 -
不要62 (acwing 1085)(数位DP)
题目地址配套地址考虑记忆化搜索的状态,设dp(i,j,k)表示处理到第i位,且上一位为j,当前是否合法为k。#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>#define int long longusing namespace std;typedef pair<int,int> pii;typedef long long ll;const原创 2021-05-13 21:11:39 · 130 阅读 · 1 评论 -
数字游戏 II(acwing 1084)(数位DP)
题目地址配套地址考虑记忆化搜索状态,dp(i,j)表示当前处理到第i位时,前面数字之和取模为j得到的值。代码#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>#define int long longusing namespace std;typedef pair<int,int> pii;typedef long long ll;cons原创 2021-05-13 20:58:08 · 100 阅读 · 0 评论 -
数字游戏 (acwing 1082)(数位DP)
题目的地址配套地址在dfs时记录一下上一个的大小,用一个变量标记构造到当前这位时,是否合法。记忆dp(i,j,k)表示处理到第i位上一位为j时,状态为k时所得到的个数。代码#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>#define int long longusing namespace std;typedef pair<int,int>原创 2021-05-13 17:45:15 · 148 阅读 · 0 评论 -
度的数量(acwing 1081)(数位DP)
题目地址配套地址每一位必须是1或者0,而且1的个数为k才算1个。dp(i,j) 表示当前处理到第i位置,且有j个1时,如果已经处理过,则返dp(i,j),否则递归。因为最大值为1,所以在枚举当前这位的数字时,必须让它小于等于1.代码#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>#define int long longusing namespace s原创 2021-05-13 16:23:06 · 331 阅读 · 0 评论 -
Super Jumping! Jumping! Jumping!(HDU1087)(线性DP)
题目地址配套地址比它小的都可以转移到当前状态#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>//#define int long longusing namespace std;typedef pair<int,int> pii;typedef long long ll;const int INF = 0x3f3f3f3f;const do原创 2021-05-04 12:20:54 · 68 阅读 · 0 评论 -
[SDOI2006]保安站岗 (洛谷p2458)(树形DP)
题目地址配套博客与 [USACO08JAN]Cell Phone Network G 一样,只是每个节点的权值不一样。#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>#define int long longusing namespace std;typedef pair<int,int> pii;typedef long long ll;c原创 2021-04-25 16:46:31 · 84 阅读 · 0 评论 -
[USACO08JAN]Cell Phone Network G(洛谷p2899)(树形DP)
题目地址配套博客设dp(i,0)表示以i安信号塔,dp(i,1)以i的儿子安装信号塔,dp(i,2)以i的父亲安装信号塔 转移dp(i,0) += min(dp(j,0),dp(j,1),dp(j,2))dp(i,2)+= min(dp(j,0),dp(j,1))。dp(i,1)可以以一个儿子安装信号塔,其它的可以选择安,或者以它儿子来安。dp(i,1)= dp(k,0)+ ∑j∈son,j≠kmin(dp[j][0],dp[j][1])\sum_{j\in{son},j\ne{k}}min(dp[原创 2021-04-25 16:34:23 · 167 阅读 · 0 评论 -
偷天换日(洛谷p33360)(树形DP)
区间DP配套博客与“访问”美术馆 基本一致。最后部分由于每一个物品不是一类,用01背包处理。#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>#define int long longusing namespace std;typedef pair<int,int> pii;typedef long long ll;const int IN原创 2021-04-25 16:13:28 · 116 阅读 · 0 评论 -
“访问”美术馆 (洛谷p1270)(树形DP)
题目地址配套博客先建立好树。树形分组背包。优化掉一维。用dp(i,j)表示以i为根节点,分配 j 的时间所取得的最大值。组内每一个物品的价值为 dp(j,y),体积为 y ,且 y < x注意如果选择了儿子,那么一定会用2 * w[i]的时间来走这一段路(来回)。最后当走到叶子节点。里面的东西都是一模一样,所以用完全背包处理(只有一类,所以只有一个循环)。#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#in原创 2021-04-25 16:00:06 · 123 阅读 · 0 评论 -
String painter(HDU2476)(区间DP)
题目地址配套博客#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>#define int long longusing namespace std;typedef pair<int,int> pii;typedef long long ll;const int INF = 0x3f3f3f3f;const double eps = 1e-5;原创 2021-04-25 14:38:14 · 121 阅读 · 0 评论 -
[USACO16OPEN]262144 P(洛谷p3147)(区间dp)
题目地址配套博客#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>#define int long longusing namespace std;typedef pair<int,int> pii;typedef long long ll;const int INF = 0x3f3f3f3f;const double eps = 1e-5;原创 2021-04-25 13:49:13 · 162 阅读 · 0 评论 -
Palindrome subsequence (HDU4632)(区间DP)
题目地址配套博客#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<iostream>#include<cstring>#define int long longusing namespace std;const int N = 1e3 + 10;const int mod = 10007;/* dp(i,j) 表示i~j中回文子序列的数量 dp(i,j) += dp原创 2021-04-20 23:30:50 · 77 阅读 · 0 评论 -
Brackets(poj2955)(区间DP)
题目i地址配套地址#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<iostream>#include<cstring>#define int long longusing namespace std;const int N = 1e2 + 10;/* dp(i,j) 表示i~j中最长的括号序列 1:当s(i) 与 s(j) 匹配时 dp(i,j) = dp(i+1,原创 2021-04-20 23:09:54 · 72 阅读 · 0 评论 -
涂色 (洛谷p4170)(区间DP)
题目地址配套地址#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>#define int long longusing namespace std;typedef pair<int,int> pii;typedef long long ll;const int INF = 0x3f3f3f3f;const double eps = 1e-5;原创 2021-04-20 22:52:29 · 260 阅读 · 0 评论 -
[USACO16OPEN]248 G (区间DP)(洛谷)
题目地址配套博客#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>#define int long longusing namespace std;typedef pair<int,int> pii;typedef long long ll;const int INF = 0x3f3f3f3f;const double eps = 1e-5;原创 2021-04-19 15:29:08 · 91 阅读 · 0 评论 -
能量项链 (洛谷)(区间DP)
题目地址附属于博客#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#include<bits/stdc++.h>#define int long longusing namespace std;typedef pair<int,int> pii;typedef long long ll;const int INF = 0x3f3f3f3f;const double eps = 1e-5;原创 2021-04-18 23:19:28 · 90 阅读 · 1 评论 -
各类动态规划(持续更新)
有误地方还请指明。比较懒,有的地方简略或者笔误。动态规划区间DP石子合并解释状态表示 dp(i,j)表示合并 i ~ j 所花费的最小价值目标状态 dp(1,n)初始化 dp(i,i) 为0转移方程 dp(i,j) dp(i,j) = min(dp(i,j),dp(i,k)+dp(k+1,j)) dp(i,j) += sum(i,j) 表示当前状态可以以k为分界点进行两堆的合并。而dp(i,k) 也可以由更小的区间进行合并.模板#include<bits/stdc++.h&原创 2021-03-24 18:36:18 · 425 阅读 · 0 评论 -
三元上升子序列(洛谷p1637)(树状数组/线段树)(扩展k元上升子序列)
题目地址预处理l[i],r[i]表示左边比它小的和右边比它大的的个数。显然,可以用树状数组或者线段树随着枚举,更新区间的值,然后查询一个区间的和,即可以得到l[],r[]。最后ans += l[i]*r[i].线段树#include<iostream>#include<algorithm>#include<vector>using namespace std;const int N = 3e4 + 10;typedef long long ll;in原创 2021-03-05 14:33:41 · 163 阅读 · 0 评论 -
饼干(acwing 277)
题目地址根据贪心,可以知道,让贪婪度越大的获取的饼干越多为好,可以用邻项交换证明。将其贪婪值从大到小排序,每一个孩子分的饼干自然单调不升。设dp[i][j] 为将j块饼干分给i个孩子获得的最小值。分配第i个孩子的时候,当大于1时,此时dp[i][j] = dp[i][j-i]。表示将每个孩子的数量减一,性质不变,且数量对应一致。当等于1时,枚举前面有多少个与之相等的。dp[i][j] = min(dp[i-k][j-k]+w)。 w(为孩子分的1块饼干所有贪婪值之和乘前面的人数)最后输出路径。原创 2021-03-01 17:53:43 · 164 阅读 · 0 评论 -
传纸条(acwing 275)
题目地址(类似方格取数)题目可以看成(两个人从起点出发到终点路径中,取得的最大值(重复点只取一次))dp(i1,j1,i2,j2)dp(i1,j1,i2,j2)dp(i1,j1,i2,j2)可以表示为第一条路径走到(i1,j1)(i1,j1)(i1,j1)点,第二条路径走到(i2,j2)(i2,j2)(i2,j2)点所取得的最大数值。但是这样设置,很难判断转移方程中,上一个点到下一个点的转移是否有重复的点被取到。所以设dp(k,i,j)dp(k,i,j)dp(k,i,j)表示为总共走了k的距离(哈密原创 2021-02-28 12:41:09 · 113 阅读 · 0 评论 -
移动服务(acwing 274)
题目地址设dp(i,x,y,z)表示处理了前i个请求,且当前三个移动服务员分别在x,y,z位置的最小值。复杂度基本为8e9,过不了。发现可以优化一维,因为处理完第i个的时候,第i个位置一定会有服务员在。故设dp(i,x,y) 表示三个服务员当前所在的位置分别在p[i],x,y。复杂度为4e7。...原创 2021-02-27 22:33:40 · 113 阅读 · 1 评论 -
分级/Making the Grade(acwing 237,poj 3666)
acwing地址poj地址首先由引理: 存在最优解,使得构造的c序列里面的每一个元素的是在a序列出现。对a排序得到A。考虑上升的情况。假设构造了一个b序列。其中存在某些b,有 A[i]<=b[l...r]<=A[i+1]A[i] <= b[l...r] <= A[i+1]A[i]<=b[l...r]<=A[i+1]统计每个b对应的a值中,有多少大于A[i+1],个数记为x,小于A[i]个数记为y。若x小于y,则可以将整个b[l…r]往下移动,直到b[l]==A原创 2021-02-27 16:43:00 · 106 阅读 · 0 评论 -
最长公共上升子序列(acwing 272)
题目地址最长公共序列和最长上升子序列的结合。设dp[i][j]dp[i][j]dp[i][j] 表示为a的前i个,b的前j个且以b[j]结尾的最长公共上升子序列。当a[i]!=b[j]a[i] != b[j]a[i]!=b[j] 当前a[i]不包含在当前最长上升子序列中。故为dp[i][j]=dp[i−1][j]dp[i][j] = dp[i-1][j]dp[i][j]=dp[i−1][j]当a[i]==a[j]a[i] == a[j]a[i]==a[j] 去掉a[i]b[j]a[i] b[j]a[原创 2021-02-11 19:42:11 · 119 阅读 · 0 评论 -
杨老师的照相排列 (acwing 271,poj2279)
题目地址所给编号序列是从大到小的。从头开始放,把第一个放到(1,1)位置,若把第一个放到其它位置,则会得不到合法排列。同理,第二个可以放到(1,2)或者(2,1)第三个放到(1,3)或(2,2)或(3,1)…可以发现性质,按序列顺序放,上一排放的个数一定大于等于下一排的个数才有解。设状态为dp[a][b][c][d][e]表示第一排放a个,第二排放b个…得到的数量。则当前状态的上一个状态可以由第一排加一个或者第二排加一个…即dp[a-1][b][c][d][e]…转移得到。需注意,上一个状态原创 2021-02-10 14:00:55 · 243 阅读 · 0 评论