OI-dp
略
嘉伟森的猫
NYU Shanghai本科,MBZUAI机器学习硕士,深度学习/强化学习菜鸡
展开
-
bzoj 4726(树形dp)
传送门从20:40想到21:40,我有时候还真是智障啊TAT。。。题解:结论1.最坏情况下初始叛徒一定是一个叶节点 结论2.最终的所有叛徒一定是某个节点为根的子树中的所有节点 定义f[p]为p的子树不叛变的最小x。f[p]=max{f[p],min{f[v],siz[v]/(siz[p]-1)}}。两个东西取min的原因:两个同时大于x才会使v的原创 2017-10-17 20:44:48 · 283 阅读 · 0 评论 -
bzoj 3384(dp)
传送门题解:设dp[i][j][k]表示前i分钟,第i分钟在k号树,以走了j次的最大收益。直接转移即可。#include#include#include#includeusing namespace std;int dp[1004][34][3],a[1004];int n,m;int main() {// freopen("bzoj 3384.in","r",st原创 2017-10-27 17:21:44 · 275 阅读 · 0 评论 -
hdu 3652(数位dp)
传送门 题解:求1~n中出现过”13”且mod 13为0的数的个数。 数位dp模板题,具体注释看代码。 注意:记忆化搜索只能记当前数位没有限制的dp值。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;int n,dp[10][13][2][10],b[1原创 2017-10-05 17:28:47 · 271 阅读 · 0 评论 -
hdu 3555(数位dp)
传送门 题解:求1~n内出现过49的数的个数。 模板题,注意long long,代码注释戳这里#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long ll;ll n,dp[64][2][10];int b[64];ll d原创 2017-10-05 19:06:22 · 227 阅读 · 0 评论 -
bzoj 1026(数位dp)
传送门 题解:裸的数位dp,注意高位0不需要满足”相邻两位之差不小于2“的条件(最高位没有之前的相邻一位)#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>using namespace std;typedef long long ll;int dp[11][10]原创 2017-10-05 19:55:26 · 232 阅读 · 0 评论 -
hdu 4734(数位dp)
传送门 题解:找出i∈[0~b]且f(i)≤f(a)的数的个数。 设dp[i][j]表示当前从高往低在第i位,f(a)被减还剩下j的方案数。 看题花的时间比做题长。。。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;int dp[11][19000],b原创 2017-10-05 20:20:59 · 245 阅读 · 0 评论 -
zoj 3640(期望dp)
传送门题解:设dp[i]表示战斗力为i 时至少花多少时间才能逃出。记忆化搜索即可。P.S.因为战斗力最多增大到maxC的两倍,所以数组要开10000*2。#include#include#include#include#include using namespace std;const double X=(sqrt(5.0)+1)/2;double dp[2000原创 2017-10-29 11:23:57 · 315 阅读 · 0 评论 -
poj 3682(期望dp)
传送门题解:设g[i]表示已经有i次正面,要到k次的期望次数。g[i]=p*g[i+1]+(1-p)*g[i]+1g[i]=g[i+1]+1/p边界:g[k]=0设f[i]表示已经有i次正面,要到k次的期望花费。f[i]=p*(f[i+1]+2*(g[i+1]+1)-1)+(1-p)*(f[i]+2*(g[i]+1)-1)移项化简即可。边界f[k]=0。P.原创 2017-10-29 11:26:16 · 492 阅读 · 0 评论 -
bzoj 4318(期望dp)
传送门题解:维护当前位为1的贡献相对上一位的一次方增量f[i]、平方增量g[i]、立方增量h[i]。因为记录的是增量,所以最后还要再加一遍。P.S.如果写成"h[i]=h[i-1]+p[i]*(f[i-1]*3+g[i-1]*3+1);"则答案就是f[n],因为之前的贡献都已经算在一起,此时h[i]定义为当前为1的对1~i的直接贡献。#include#include#inc原创 2017-10-29 12:26:04 · 476 阅读 · 1 评论 -
bzoj 3450(期望dp)
传送门题解:设f[i]表示1~i的期望收益,len[i]表示i尾部连续的'0'期望长度。若s[i]=='x',则f[i]=f[i-1],len[i]=0,若s[i]=='o',则f[i]=f[i-1]+len[i-1]*2+1,len[i]=len[i-1]+1,若s[i]=='?',则f[i]=f[i-1]+(len[i-1]*2+1)/2,len[i]=len[i-1]/2原创 2017-10-27 15:50:01 · 326 阅读 · 0 评论 -
poj 3311(浅谈状态压缩动态规划在解决TSP问题中的应用)
传送门 题意: 给出0~n个点两两的路径长度,求出从0号点出发遍历1~n每个点一次再回到0号点的最小花费。注意同一对点来回路径可能不等长! 题解: 经典的TSP问题(以下内容摘自百度百科):TSP问题是一个组合优化问题。该问题可以被证明具有NPC计算复杂性。因此,任何能使该问题的求解得以简化的方法,都将受到高度的评价和关注。定义dp[st][pos]表示当前0/1状态为st位置在pos的最小原创 2017-10-10 19:10:05 · 636 阅读 · 0 评论 -
hdu 4336(状压+期望dp)
传送门 题意:有n(1<=n<=20)张卡片,每包中含有卡片的概率为p1,p2……pn。每包最多有一张卡片,可能没有卡片。求需要买多少包才能凑齐N张卡片,求次数的期望。 真是把2016NOIP两道压轴题的算法都用到了!第一次见到状压和期望一起考的。此题比较水,直接枚举卡片倒推即可。#include<cstdio>#include<cstring>#include<iostream>#inc原创 2017-10-10 19:42:10 · 302 阅读 · 0 评论 -
bzoj 1596(树形dp)
传送门题解:定义dp[0/1/2][i]表示在子树所有节点均被覆盖的前提下,当前节点被子树中的点覆盖/自己覆盖/不被覆盖,需要的通讯塔个数(子树中)定义dp[2][pos]目的是将其转移给dp[0][father]。dp[0][p]=∑dp[2][son]dp[1][p]=∑min{dp[0][son],dp[1][son],dp[2][son]}dp[2][p]=min{原创 2017-10-18 08:44:42 · 281 阅读 · 0 评论 -
Luogu 1141(dp)
传送门NOIP 2010 T2题解:切入点:使用同等数量的各种卡牌,走到的位置是一样的。定义dp[i][j][k][h]为使用了i张1号卡,j张2号卡,k张3号卡,h张4号卡。然后转移即可,注意起点为1。#include#include#include#includeusing namespace std;int dp[42][42][42][42];int n原创 2017-10-18 17:05:33 · 280 阅读 · 0 评论 -
hdu 2571(dp)
传送门题解:定义dp[i][j]为走到(i,j)的最大收益。为了防止枚举因数,建议用当前状态更新未来状态。转移方程略,自己yy吧。#include#include#include#includeusing namespace std;const int INF=0x3f3f3f3f;int n,m,a[24][1004];int dp[24][1004];inlin原创 2017-10-18 20:01:07 · 266 阅读 · 0 评论 -
hdu 1078(记忆化搜索)
传送门题解:简单记忆化搜索。#include#include#include#includeusing namespace std;const int MAXN=104;int n,m;int a[MAXN][MAXN];int dp[MAXN][MAXN];int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};inline int read(原创 2017-10-18 20:59:22 · 224 阅读 · 0 评论 -
bzoj 2287(背包dp)
传送门题解:设f[i]为装满i的容量的方案数,可以按01背包的方法O(nm)预处理。设g[i][j]表示不用i,装满j的容量的方案数。对于每个i:若i否则g[i][j]=f[j]-g[i][j-v[i]]由于每个物品单独考虑互不影响,所以g数组可以去掉第一维。P.S.听说可以用什么分治背包?以后再说。。。#include#include#incl原创 2017-10-18 21:41:25 · 256 阅读 · 0 评论 -
poj 1821(单调队列优化dp)
传送门 题解: 定义dp[i][j]为前i个人涂j块木板的最大收益。 显然dp转移方程如下: dp[i][j]=max{dp[i][j],dp[i-1][k]+(j-k)*p[i].w} 其中k∈[max(0,p[i].s-p[i].len),min(p[i].s-1,j)] 用单调队列维护dp[i-1][k]-k*p[i].w即可。单调队列真是又一个大盲点啊。。。蒟蒻赶紧学。。。#in原创 2017-10-10 16:34:30 · 369 阅读 · 1 评论 -
bzoj 3036(期望dp)
传送门题解:1A,稳。我感觉好像~似乎~也许~学会期望dp的皮毛了。。。#include#include#include#includeusing namespace std;const int MAXN=1e5+4,MAXM=MAXN<<1;int head[MAXN],etot=0;struct EDGE { int v,nxt,w;}e[MAXM];d原创 2017-10-29 15:35:32 · 409 阅读 · 0 评论 -
bzoj 4008(浅谈全局整体考虑设计状态实现期望dp)
传送门题意:给出n个技能,每个技能按输入顺序有p[i]的概率释放并造成d[i]的伤害。每轮游戏只能发动一个技能,问r轮游戏一共能造成的伤害期望。题解:神dp?!%%%因为单独考虑每一轮很难设计出无后效性的状态(反正我是没想出来~~~于是看题解),将每一轮合(ho)在一起考虑。于是最神的一招来了:设f[i][j]表示第i个技能有j次机会的概率。先列出转移方程再解释:原创 2017-10-29 15:38:47 · 399 阅读 · 1 评论 -
bzoj 1419(期望dp)
传送门题解:设f[i][j]表示已经使用了i张红牌,j张黑牌的最大期望收益。转移方程:f[i][j]=max(0.0,1.0*i/(i+j)*(f[i-1][j]+1)+1.0*j/(i+j)*(f[i][j-1]-1))边界:f[i][0]=i直接做要MLE,所以第一维采用滚动数组优化。#include#include#include#includeusi原创 2017-10-29 16:38:34 · 408 阅读 · 0 评论 -
hdu 3182(状压dp)
传送门题解:略,满足条件就转移,否则不转移,完了。调了一晚上。。。只有复杂度允许,能for的就for(比如dp时内层对n的循环),不要为了追求一点速度就去写什么lowbit来提取二进制的1,此可谓弄巧成拙。#include#include#include#includeusing namespace std;int n,m,v[16],c[16],pre[16];i原创 2017-10-25 22:36:17 · 263 阅读 · 0 评论 -
bzoj 1037(dp)
传送门dp神题。dp[i][j][k][h]表示前i个人有j个男生,任意连续段中,男生最多多出k个,女生最多多出h个的方案数。答案为所有dp[n+m][n][k][h](k#include#include#include#includeusing namespace std;const int MOD=12345678;int n,m,K,ans=0,dp[304][1原创 2017-10-26 14:54:58 · 249 阅读 · 0 评论 -
bzoj 1617(dp)
传送门机房外面运动会,机房里面刷水题。。。记录一个代价前缀和,直接dp即可。注意:最后的答案要减去一次单人过河的代价,因为最后一次过河不用返程。#include#include#include#includeusing namespace std;const int MAXN=2504;int s[MAXN],dp[MAXN];int n;inline int re原创 2017-10-26 16:25:47 · 264 阅读 · 0 评论 -
bzoj 1978(dp)
传送门题解:对于每个数x枚举因子i,记录上一个能整除i的位置,从这个位置转移过来,取max即可。#include#include#include#includeusing namespace std;int n,L,dp[50004],nxt[1000004],ans=0;inline int read() { int x=0;char c=getchar(); whi原创 2017-10-26 17:21:31 · 345 阅读 · 0 评论 -
Luogu 1387(dp)
传送门 我也不知道它为什么是dp。。。显然01矩阵中全为1的正方形有一个性质,那就是权值和为边长平方。那乱搞一下不就行了吗。。。 注意:ans初值赋为1。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN=102;int n,m原创 2017-08-23 15:15:15 · 298 阅读 · 0 评论 -
bzoj 1076(状压dp)(期望dp)
传送门 题解:dp[i][j]表示第i轮状态为j的最大期望得分。为了防止从无效状态转移至有效状态,采用倒推法,从已知的有效状态往回推,具体注释在代码中。 P.S.不写memset可以快接近一倍,但是为了思维严密性,还是写一个,反正都能过(´∇`)#include<bits/stdc++.h>using namespace std;const int MAXN=17;int K,n,temp原创 2017-09-04 23:00:10 · 311 阅读 · 0 评论 -
bzoj 1237(dp)
传送门 题解:排序我是想到了的,毕竟能贪心的要先贪心。之后怎么交换呢,肯定是当前数往前放,前面的依次往后平移,交换两个数有1种换法,交换三个数有2种换法。有一个重要结论:所有大于3的数都可以分解成3x+2y的形式,所以就解决啦!对于不少于四个数的序列,直接“平移式”交换一定不如拆成若干个3和2交换优。 #include<bits/stdc++.h>using namespace std;ty原创 2017-09-18 10:43:50 · 433 阅读 · 0 评论 -
Luogu 1279 字串距离(dp)
题目描述设有字符串X,我们称在X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为”abcbcd”,则字符串“abcb□cd”,“□a□bcbcd□”和“abcb□cd□”都是X的扩展串,这里“□”代表空格字符。如果A1是字符串A的扩展串,B1是字符串B的扩展串,A1与B1具有相同的长度,那么我扪定义字符串A1与B1的距离为相应位置上的字符的距离总和,而两个非空格字符的距离定义...原创 2018-03-30 16:57:29 · 409 阅读 · 0 评论 -
bzoj 3594(树状数组优化dp)
传送门题解:设dp[i][j]表示前i个玉米用j次操作的LIS长度。dp[i][j]=max{dp[x][y]}+1(x维护一个关于(j,max{a[i]}+j)的树状数组,每次倒序枚举j防止dp[i]内部自己更新自己,如果正序枚举可能发现这种情况:dp[i][k]更新到后来dp[i][j](k由dp转移式知dp[i][...]只能被dp[比i小的数][...]更新到。原创 2017-10-16 19:56:12 · 313 阅读 · 0 评论 -
bzoj 1087(状压dp)
传送门题解:先预处理st[i]和num[i]两个数组,表示第i个自身合法的状态是啥以及它有多少个1,定义d[i][j][k]表示前i行,当前行为i状态并且还剩k个国王的方案数,从上往下递推即可。P.S.希望下次不要再因为什么longlong之类的错失1A的良机qwq。。。#include#include#include#includeusing namespace std;原创 2017-10-16 19:18:40 · 245 阅读 · 0 评论 -
hihocoder 1043(完全背包)
传送门模板题,正着for。#include#include#include#includeusing namespace std;int c[502],v[502];int n,m;int f[100004];inline int read() { int x=0;char c=getchar(); while (c'9') c=getchar(); while (c原创 2017-11-09 20:40:32 · 319 阅读 · 0 评论 -
bzoj 1616(dp)
传送门题解:设dp[t][i][j]为第t秒走到(i,j)的方案数,边界dp[0][sx][sy]=1。O(T*nm)暴力递推方案数即可,注意变量枚举顺序。也可以用搜索过。#include#include#include#includeusing namespace std;const int MAXN=104;int dp[17][MAXN][MAXN];char原创 2017-10-21 16:30:43 · 234 阅读 · 0 评论 -
hdu 3853(期望dp)
传送门 题解: 设dp[i][j]表示从(i,j)走到(n,m)的期望花费,倒推即可。 P.S.小心停留概率为1的情况,必须跳过,否则会除0。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN=1004;double dp[M原创 2017-07-30 14:42:05 · 343 阅读 · 0 评论 -
Luogu 1311(dp/模拟)(NOIP 2011)
传送门NOIP 2011 D1T2题解:1.dp,有O(n),下面是三月份测试写的O(n*k)的:#include#include#include#includeusing namespace std;const int maxn=200004;int n,k,p;//客栈数,色调数,max int c,m;//色调,花费int num[maxn][51],s[ma原创 2017-10-22 21:57:20 · 257 阅读 · 0 评论 -
Luogu 2679(dp)(NOIP 2015)
传送门NOIP 2015 D2T2题解:定义dp[i][j][k]为a串前i个字符,b串前j个字符,分成k段的方案数(a[i]必须选)。定义sum[i][j][k]为a串前i个字符,b串前j个字符,分成k段的方案数(a[i]可选可不选)。直接来要爆空间,所以第一维采用滚动数组优化。那么两个数组互相转移:dp[cur][j][k]=sum[cur^1][j-1][k-1]原创 2017-10-13 19:48:05 · 201 阅读 · 0 评论 -
bzoj 1426(期望dp)(公式推导)
传送门题解:反正就是想尽一切办法去掉极限。#include#include#include#includeusing namespace std;const int MAXN=10004;double g[MAXN],f[MAXN];int n;int main() { scanf("%d",&n); g[n]=0; for (int i=n-1;~i原创 2017-10-27 15:07:40 · 389 阅读 · 0 评论 -
tvyj 1313(单调队列优化dp)
传送门 题解: 设dp[i]表示以1~i范围内(保证i处放一个烽火台)的最小代价。 dp[i]=min{dp[j]+w[i]}(i-j+1<=m) 用一个单调递增的队列维护dp数组,每次用队首更新答案,将元素插入队尾。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespac原创 2017-10-15 12:20:14 · 403 阅读 · 0 评论 -
hdu 3401(单调队列优化dp)
传送门 题解: 构造状态dp[i][j]表示第i 天拥有 j只股票的时候,赚了多少钱 从前一天不买不卖 dp[i][j]=max(dp[i-1][j],dp[i][j]) 从前i-W-1天买进一些股 dp[i][j]=max(dp[i-W-1][k]-(j-k)*AP[i],dp[i][j]) 从i-W-1天卖掉一些股 dp[i][j]=max(dp[i-W-1][k]+(k-j)*BP[原创 2017-10-15 17:36:35 · 395 阅读 · 0 评论 -
hihocoder 1038(01背包)
传送门模板题,倒着for,复杂度O(n*maxV)。#include#include#include#includeusing namespace std;int c[502],v[502];int n,m;int f[100004];inline int read() { int x=0;char c=getchar(); while (c'9') c=getch原创 2017-11-09 20:36:39 · 249 阅读 · 0 评论