---------dp-----------
Icefox_zhx
这个作者很懒,什么都没留下…
展开
-
luogu1970【2013提高】花匠(DP/贪心)
求最长抖动序列。首先很直白的dp:令f[i][1]表示以i为结尾,且降序到达a[i]的最长抖动序列长度;令f[i][0]表示以i为结尾,且升序到达a[i]的最长抖动序列长度。则有如下递推公式: f[i][0]=max{f[j][1]}+1,1≤j<i且h[j]<h[i]f[i][0]=max\{f[j][1]\}+1,1≤j<i且h[j]<h[i] f[i][1]=max{f[j][0]}+1原创 2017-07-29 15:02:19 · 329 阅读 · 0 评论 -
luogu1077【2012普及】 摆花(dp)
f[i][j]表示用前i种花,摆j盆的方案数。原创 2017-07-29 11:05:24 · 327 阅读 · 0 评论 -
luogu1057【2008普及】传球游戏(dp)
f[i][j]表示第i次传球后,球在第j位。#include<cstdio> #include<cstring> int n,m,f[50][50]; int main(){ //freopen("a.in","r",stdin); scanf("%d%d",&n,&m); memset(f,0,sizeof(f)); f[0][1]=1; //第0次传球原创 2017-07-29 16:13:27 · 297 阅读 · 0 评论 -
luogu1020【1999提高】导弹拦截(dp)
求最长不上升子序列的板子。 这道题,对于最长上升子序列来说,每一个点都只能用一套新的导弹系统来拦截。原创 2017-07-29 16:24:52 · 269 阅读 · 0 评论 -
ural1183&&poj1141 Brackets Sequence(区间DP+记录路径)
黑书动规1.5.1例题1,原题多了记录路径,要递归打印出来。 dp[i][j]表示s[i…j]需加至少多少个括号才能变成合法的。原创 2017-07-29 11:47:27 · 275 阅读 · 0 评论 -
luogu1091【2004提高】合唱队形(dp)
#include<cstdio>int n,a[101],f1[101],f2[101],ans=0;int main(){ //freopen("a.in","r",stdin); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++){ //求从左到右最长上原创 2017-07-29 16:35:56 · 262 阅读 · 0 评论 -
luogu1280 尼克的任务(dp)
倒着推,f[i]表示此时刻开始选择工作,能获得的最大休息时间。 状态转移: if(这时刻没工作)f[i]=f[i+1]+1; if(这时候有一或多个工作)f[i]=max( f[ i+k[i] ] ); ps:应该按开始时间排下序的。。我懒忘敲了居然A了。。#include<cstdio>#include<cstring>#include<iostream>using namespac原创 2017-07-29 16:51:09 · 340 阅读 · 0 评论 -
sicily1822 Fight club(dp)
黑书1.5.1例题3 1822 . Fight Club原创 2017-07-30 12:37:29 · 397 阅读 · 2 评论 -
uva1291 Dance Dance Revolution(dp)
黑书1.5.1例题4.舞蹈家怀特先生。 dp[i][x][y] 表示跳完第i个舞步,左脚在x,右脚在y所需花费的最小体力。状态转移方程: dp[i][x][a[i]]=min(dp[i][x][a[i]],dp[i−1][x][y]+move(y,a[i]))dp[i][x][a[i]]=min(dp[i][x][a[i]],dp[i-1][x][y]+move(y,a[i]))dp[i][a[原创 2017-07-30 13:22:52 · 320 阅读 · 0 评论 -
luogu1004 【2000提高】方格取数(dp)
这水题我居然还想了半天。。傻死我自己得了。首先要明确,两次从(1,1)走到(n,n)都需要走2*n步。所以可以两次一起走。对于一个点(m,n)两次都只可能在走第m+n步时经过,所以只需在当次判断是否重复,其他时候都绝对不会重复。朴素的是dp[x1][y1][x2][y2],第一次走到x1,y1,第二次走到x2,y2.O(n4)O(n^4),优化一下,dp[k][i][j],走到第i步了,第一次向下走原创 2017-07-30 18:04:33 · 525 阅读 · 0 评论 -
cogs261 [NOI1997] 积木游戏(dp)
黑书1.5.1例题5 积木游戏 刚开始想按黑书那样去写,四层状态,倒着推。然后,2h过去了,爆炸。从网上搜了搜,等等,你们怎么都就三层状态?认真看一下,woc,我一定是傻疯了写四层。然后瞬间ac。看到一个写四层的,基本都是记忆化搜索过了。我倒推好弱。。推不明白。还是正推好一些。。(网上神犇纷纷表示,这是一道dp水题,好吧orz)说正解,基本都写注释里了:)状态O(mn)O(mn),决策O(n)O(原创 2017-07-30 16:28:51 · 376 阅读 · 0 评论 -
bzoj4745[USACO16DEC]Cow Checklist (DP)
d数组是两点间距离的平方,提前处理。状态数O(n2)O(n^2),决策数和转移都是O(1)O(1)的原创 2017-07-30 20:35:19 · 480 阅读 · 0 评论 -
bzoj1270 [BeijingWc2008]雷涛的小猫(dp)
比较水的dp,dp[i][j]表示高度为i,在第j棵树上时能获得的最大值。状态转移方程:dp[i][j]=max(dp[i+1][j],dp[i+del][?])+f[j][i]。为了让决策变成O(1)的,我们带着个数组f。f[i]表示在高度i时能获得的最大值。这样决策就变成O(1)得了。转移是O(1)O(1)的,状态是O(nh)O(nh)的,总的时间复杂度是O(nh)O(nh)的。原创 2017-07-30 21:30:04 · 285 阅读 · 0 评论 -
luogu1052 【2005提高】过河 (压缩状态)
显然的状态转移方程:dp[i]=min(dp[i-j]+stone[i],s<=j<=t),然而L过大,我们要想办法压缩。我们把石子按位置升序排序,设第i块石子的位置为x,第i+1块石子的位置为y。如果y-x>t,那么对于x+t+p<<y,dp[x+t+p]一定是dp[x+p]…dp[x+t+p-1]中的某个值。重复了,因此我们可以只留t个点。对于y本来可能取到的最优值,他一定在留下的t个点之内。至原创 2017-07-31 14:52:24 · 440 阅读 · 0 评论 -
luogu1048 【2005普及】采药(背包dp)
01背包。原创 2017-07-31 15:54:53 · 315 阅读 · 0 评论 -
luogu1049 【2001普及】装箱问题(dp)
f[i]表示能否装出i这个体积。枚举即可。找到能装的最大合法体积。原创 2017-07-31 13:22:50 · 271 阅读 · 0 评论 -
bailian4102:宠物小精灵之收服(二维费用的01背包)
dp[i][j]表示扔i个球,皮卡丘损失j体力时所能抓到的最大精灵数。相当于二维费用的01背包。最后按皮卡丘损失体力从小到大扫一下,为了找最优解时皮卡丘剩余体力的最大值。原创 2017-08-07 16:13:35 · 456 阅读 · 0 评论 -
bailian4122:切割回文(区间dp)
dp[i]表示把前i个都变成回文串最少需要切割的次数。每次枚举在j后面切一刀,暴力判断(j+1,i)是否是回文,如果是,那就是要切割dp[j]+1次。取最小即可。原创 2017-08-07 16:25:39 · 575 阅读 · 0 评论 -
hdu1712 ACboy needs your help(分组背包板子)
分组背包板子。 问题 有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 算法 这个问题变成了每组物品有若干种策略:是选择本组的某一件,还是一件都不选。也就是说设f[k][v]表示前k组物品花费费用v能取得的最大权值,则有:原创 2017-08-07 16:34:47 · 362 阅读 · 0 评论 -
bzoj1597 [Usaco2008 Mar]土地购买(变形+斜率优化)
一开始的题目,只是给我们n块随机的地,让我们分组,可以往的1D1D形式的dp一般都会要求每组中序号都是连续的,这样我们才可以进行dp。那此题怎么办呢?首先有个显然的优化:如果x1<=x2&&y1<=y2则(x1,y1)完全可以和(x2,y2)打包在一起购买而不用付出额外的花费,因此(x1,y1)就可以不再考虑了。所以我们把所有的地按x为第一关键字,y为第二关键字进行升序排序,把可以和别的地“打包”购原创 2017-08-07 17:54:27 · 382 阅读 · 0 评论 -
P1064 金明的预算方案【2006提高】(背包)
v[i][0]主件,v[i][1]附件1,v[i][2]附件2.每次决策时最多四种。转化为01背包。原创 2017-07-31 16:22:13 · 417 阅读 · 0 评论 -
CF 833B The Bakery(dp+线段树)
题意:把n个数分成k部分,使得每部分价值之和最大。每部分的价值为不同数的个数。很容易的可以想到dp,用dp[i][k]表示把前i个数分成k部分所获的最大值。则dp[i][k]=max(dp[j][k−1]+num[j+1][i],k−1≤j<i)dp[i][k]=max(dp[j][k-1]+num[j+1][i],k-1\leq j<i) num[i][j]表示a[i..j]的不同数的个数,但是原创 2017-07-31 21:05:52 · 2006 阅读 · 0 评论 -
CF835D Palindromic characteristics(dp)
题目大意:给你一个串,让你求出k阶回文子串有多少个。k从1到n。k阶子串的定义是:子串本身是回文串,而且它的左半部分也是回文串。首先明确: 1、如果一个字串是k阶回文,那他一定还是k-1阶回文。 2、如果一个串是k阶回文,那么这个串需要满足: 1.它本是是回文的。 2.他的左半部分是k-1回文的。 有点递归的意思。。所以我们采用dp。 dp[i][j]表示子串s[i..j]最大是几阶的,原创 2017-08-01 12:51:55 · 712 阅读 · 0 评论 -
bzoj1009 [HNOI2008]GT考试(KMP+DP+矩阵倍增)
f[i][j]表示前i位准考证号,匹配到了不吉利串第j位。我们考虑如何将f[i][j]转移到f[i+1][j].首先用kmp处理出fail数组,假设现在在做前i位匹配到了第j位,那么对于i+1位可能出现的每个字符我们都从j开始匹配,看能转移到哪里去。就是这样: f[0][0]=1; for(int i=0;i<=n;i++){ for(int j=0;j<m;j++){ for(i原创 2017-07-23 21:58:51 · 404 阅读 · 0 评论 -
CEOI 2004 two 锯木厂(cogs)(斜率优化)
Description 从山顶上到山底下沿着一条直线种植了n棵老树。当地的政府决定把他们砍下来。为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂。 木材只能按照一个方向运输:朝山下运。山脚下有一个锯木厂。另外两个锯木厂将新修建在山路上。你必须决定在哪里修建两个锯木厂,使得传输的费用总和最小。假定运输每公斤木材每米需要一分钱。 你的任务是编写一个程序,从输入文件中读入树的个数和原创 2017-08-05 20:37:20 · 659 阅读 · 0 评论 -
bzoj3437小P的牧场(斜率优化)
这题就是锯木厂那道的简化版。。只不过是每个点之间的距离都变成1了。。详见锯木厂。f[i]=min{f[j]+c[i]-c[j]-sw[i]*(i-j)| 0<=j< i}+a[i]。表示在i建控制站,上一个控制站建在j所需的最小花费。假设k1< k2且k1优于k2,则有(f[k2]-f[k1]+c[k1]-c[k2]+sw[k2]*k2-sw[k1]*k1)/(sw[k2]-sw[k1])>i。因此原创 2017-08-08 14:57:18 · 335 阅读 · 0 评论 -
bzoj4518 [Sdoi2016]征途 (斜率优化)
求方差的套路见过了,所以直接A掉了hh 答案表示一下就是∑i=1m(x¯−xi)2m∗m2\frac{\sum\limits_{i=1}^m(\overline{x}-x_i)^2}{m}*m^2,其中x¯=∑i=1mxim\overline x =\frac{\sum\limits_{i=1}^mx_i}{m},记前缀和sum,则sum[n]显然就是∑i=1mxi\sum\limits_{i=1原创 2017-08-08 17:38:07 · 382 阅读 · 0 评论 -
bzoj3675 [APIO2014] 序列分割(斜率优化)
首先我们根据这个分割的过程可以发现:总得分等于k+1段两两的乘积的和(乘法分配律),也就是说与分割顺序是无关的。再对乘积进行重分组(还是乘法分配律)我们可以转化为:ans=∑第 i 段×前 i-1 段的和,那我们可以认为这k+1段是从左到右依次分出来的。假设目前这段是j+1…i,则他对答案的贡献为(sum[i]-sum[j])*sum[j].这样就很容易可以得到O(kn2)O(kn^2)的状态转移方原创 2017-08-08 16:24:31 · 371 阅读 · 0 评论 -
[noi模拟赛]math (斜率优化,未测)
拖了许久的坑。。 sum[i]=∑t=1ia[t]sum[i]=\sum\limits_{t=1}^ia[t] sum1[i]=∑t=1i1a[t]sum1[i]=\sum\limits_{t=1}^i\frac{1}{a[t]} sum2[i]=∑t=1isum[t]a[t]sum2[i]=\sum\limits_{t=1}^i\frac{sum[t]}{a[t]} f[i][k]前i个数原创 2017-08-08 22:35:19 · 319 阅读 · 0 评论 -
uoj149【2015提高】子串(dp)
f[i][j][k]表示 a前i个字符匹配了b的前j个字符 分了k段 的方案数,s[i][j][k]表示 a前i个字符匹配了b的前j个字符且a的第i个字符一定匹配了b的第j个字符 分了k段 的方案数。考虑转移到f[i][j][k]: 对于a[i]无非两种决策: 1.不匹配b[j],则方案数为f[i-1][j][k]。 2.匹配b[j],则方案数为s[i][j][k]。 s[i][j][k]如原创 2017-08-15 23:11:34 · 257 阅读 · 0 评论 -
bzoj1087 [SCOI2005]互不侵犯King(状压dp)
压缩每一行的状态,1表示放国王,0表示不放国王,则一行有2n2^n种状态,预处理每行的可能合法状态,即相邻的位置不能同为1,顺便记录cnt,表示此状态放了多少个国王(即状态i有多少个位为1)。然后再预处理相邻两行的合法状态(相同位置不同为1,左上右下相邻位置不同为1,左下右上相邻位置不同为1)。dp[i][j][k]表示前i行一共放了j个king,第i行状态为k的方案总数,则 dp[i][j][k原创 2017-08-16 10:11:29 · 288 阅读 · 0 评论 -
bzoj1725 [USACO2006NOV]Corn Fields牧场的安排(状压dp)
跟上一题很像啊。。这题n=12,每行的状态也不太一样,所以我们就不预处理了。dp[i][k]表示第i行的状态为k的合法方案,等于第i-1行状态为j且j,k可以为相邻行的方案数的和原创 2017-08-16 10:44:48 · 435 阅读 · 0 评论 -
poj1038 Bugs Integrated, Inc.(3进制状压dp)
黑书1.5.2例题10 Bugs公司 一看m和n差这么多,才10,很有可能是状压。我们这样看好别扭。。把他转一下,变成n*m的矩形,那要压缩一定是把一行压成一个状态。考虑到放的小矩形是3*2或2*3的,会影响(i,x)能否放矩形的只有(i-1,x),(i-2,x)。所以我们用pre[x]这样表示: pre[x]=0->(i-2,x),(i-1,x)均空闲 pre[x]=1->(i-2,x)被占原创 2017-08-16 11:55:38 · 349 阅读 · 0 评论 -
bzoj1925 [Sdoi2010]地精部落(dp)
程序5分钟,思维两小时hh。 问题就是求长度为n的排列满足抖动序列的个数。我们首先要发现答案是具有对称性的,即如果存在一个排列满足答案且第一个数为山峰,则一定还存在一个排列满足答案且第一个数为山谷(把原排列中的每个数x都换成n+1-x即可),推广一下:如果存在一个长度为i的序列满足要求且第一个数为山峰的话,则一定还存在一个长度为i的序列满足要求且第一个数为山谷(把这i个数从小到大排列,分别为a[1原创 2017-08-16 14:54:54 · 373 阅读 · 0 评论 -
poj1390 Blocks(区间dp)
黑书1.5.2例题1 方块消除 首先把相邻的同色块合并成一块,记录col[i],len[i],tot[i]此块后面可能再接的最大长度。用dp[i][j][k]表示区间i…j,在j块以右又接了长度k的最高得分。现在考虑第j块后面接了长度k,我们有两种策略: 1、直接消掉,那么得分就是dp[i][j−1][0]+(len[j]+k)2dp[i][j-1][0]+(len[j]+k)^2 2、在i…原创 2017-08-01 21:54:22 · 465 阅读 · 0 评论 -
bzoj2538&&hdu4844 [CTSC2000]公路巡逻(dp)
黑书1.5.2例题2 公路巡逻 首先对于时刻的处理,我们以六点整为0s,把所有时刻都换成s。然后根据最大和最小速度以及10Km,我们可以知道目标车从i关口到i+1关口需要300~600s的时间,到达i关口的最小时间为(i-1)*300,最大时间为(i-1)*600.我们设k为相邻关口行驶时间的可能数目(300),则最大时间是O(nk)的,用dp[i][t]表示在时间t到达关口i,与巡逻车最少相遇的原创 2017-08-02 12:22:12 · 663 阅读 · 0 评论 -
CF494B Obsessive String(KMP+DP)
这道题的题目真是太难读了。。。推了半天样例。其实就是让你求合法的集合数目。合法的集合定义为:1、集合中的所有串都是s的子串,且互不重叠 2、集合中的所有串都含有子串t。设串s长度为n,串t长度为m,我们首先用kmp在s中匹配t,匹配成功的位置我们打下标记flag[i]=1(s[i-m+1...i]=t[1..m]).以下角标均针对串s:设dp[i]表示合法且集合中最后一个子串为s[j.原创 2017-07-24 22:23:00 · 708 阅读 · 0 评论 -
hdu5791 Two(dp求公共子序列个数)
求两个序列的公共子序列个数,dp[i][j]表示a序列前i个和b序列前j个公共子序列个数。由容斥原理dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]。特别的,如果a[i]==b[j],会创造更多的公共子序列,即dp[i][j]+=dp[i-1][j-1]+1.(不带a[i],b[j]的公共子序列都在加上a[i],b[j]构成新的公共子序列,再加上1个a[i],b原创 2017-08-16 16:36:46 · 460 阅读 · 0 评论 -
FZU2129 子序列个数(dp求不同子序列个数)
dp[i]表示前i个数的不同子序列个数,对于a[i] 1.在之前没出现过,dp[i]=dp[i-1]+dp[i-1]+1 2.在之前出现过,最近的位置为x,dp[i]=dp[i-1]+dp[i-1]-dp[x-1]原创 2017-08-16 16:59:06 · 2549 阅读 · 0 评论 -
bzoj1899 [Zjoi2004]Lunch 午餐(dp)
首先不难证明吃饭慢的人一定要先打饭。(吃饭快的排在他前面,那只会使最后所有人吃完饭的时间更长)因此,我们先以吃饭时间由大到小排序,这样就可以只用排队时间来表示状态了。f[i][j]表示前i个人在1号口打饭排队所花的时间为j时所有人吃完饭的最小时间,sum[i]为排队时间的前缀和,则在2号口打饭排队所花时间为sum[i]-j.对于第i个人,无非两种决策: 1.在1号口打饭,则f[i][j]=max{原创 2017-08-16 19:53:02 · 390 阅读 · 0 评论