- 博客(81)
- 资源 (3)
- 收藏
- 关注
原创 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 2007
原创 P1064 金明的预算方案【2006提高】(背包)
v[i][0]主件,v[i][1]附件1,v[i][2]附件2.每次决策时最多四种。转化为01背包。
2017-07-31 16:22:13 418
转载 背包九讲
背包九讲 目录 第一讲 01背包问题 第二讲 完全背包问题 第三讲 多重背包问题 第四讲 混合三种背包问题 第五讲 二维费用的背包问题 第六讲 分组的背包问题 第七讲 有依赖的背包问题 第八讲 泛化物品 第九讲 背包问题问法的变化 附:USACO中的背包问题 前言 本篇文章是我(dd_engi)正在进行中的一个雄心勃勃的写作计划的一部分,这个计划的内容
2017-07-31 15:56:29 385
原创 P1095 守望者的逃离【2007普及】(贪心)
说实话我都有点分不清这是贪心还是dp了。。。说dp吧连个状态都没有。。。还是算他贪心吧。。。假设有两个人一起逃跑,一个只run,一个只blink(没蓝了就停下回蓝),如果blink大于run了,run就拿过blink来接着跑。。所以run就是t0时跑的最远距离了。
2017-07-31 15:15:21 417
原创 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
原创 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 287
原创 bzoj4745[USACO16DEC]Cow Checklist (DP)
d数组是两点间距离的平方,提前处理。状态数O(n2)O(n^2),决策数和转移都是O(1)O(1)的
2017-07-30 20:35:19 481
原创 luogu1018【2000提高】乘积最大(区间dp)
dp[i][k]表示在1..i切k刀,分成k+1部分的最大乘积。a[i][j]表示s[i…j]这个数。状态数O(nm)O(nm),预处理O(n2)O(n^2),决策O(n)O(n),转移O(1)O(1),总的时间复杂度O(n2m)O(n^2m)。按照题目叙述应该高精,太懒没写。。居然水过。。。嗯,noip嘛,骗分就好了。 upd:最新版看这里:传送门
2017-07-30 20:17:03 390
原创 luogu1043【2003普及】数字游戏(区间dp)
在后面再复制一遍,把环变成链。dp[k][i][j]表示把i…j(包括i,j)分成m部分能获得的最值。状态数O(mn2)O(mn^2),决策O(n)O(n),转移时间O(1)O(1),总的时间复杂度O(mn3)O(mn^3)
2017-07-30 20:07:14 491
原创 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 526
原创 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 378
原创 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 322
原创 luogu1880 合并石子(区间dp)
环形石子堆,我们首先要拉成直链(在后面复制一遍即可)。然后区间dp,dp1[i][j]表示合并第i到j堆的最小得分。最后答案就是min{dp[i][i+n−1]}(1≤i≤n)min\{dp[i]\left[i+n-1\right]\}(1\leq i\leq n).最大得分同理。时间复杂度O(n3)O(n^3)
2017-07-29 17:21:51 373
原创 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 341
原创 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
原创 luogu1020【1999提高】导弹拦截(dp)
求最长不上升子序列的板子。 这道题,对于最长上升子序列来说,每一个点都只能用一套新的导弹系统来拦截。
2017-07-29 16:24:52 270
原创 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
原创 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 330
原创 ural1183&&poj1141 Brackets Sequence(区间DP+记录路径)
黑书动规1.5.1例题1,原题多了记录路径,要递归打印出来。 dp[i][j]表示s[i…j]需加至少多少个括号才能变成合法的。
2017-07-29 11:47:27 277
原创 luogu2196 【1996提高】挖地雷(记忆化搜索/dp)
这道题以前写的时候想不明白为什么能dp,所以固执的写了记忆化搜索。。。现在一想其实很简单,这道题给的图其实是很特殊的,每个点只可能与在它后面的点有有向边。所以可以倒着dp,满足了无后效性和最优子结构。dfs+记忆化
2017-07-29 10:49:19 319
原创 poj2752 Seek the Name, Seek the Fame(kmp)
从len开始,每一个fail[len]都可以。。不过要倒着输出。。
2017-07-28 22:26:42 265
原创 bzoj2342 [Shoi2011]双倍回文(manacher+暴力/set)
题意:求一个最长的回文串,满足它的后半段也是个偶数回文串。 首先用manacher处理出f数组,表示以i,i+1为对称轴的最长偶数回文的长度的一半(根据题目不难发现只有偶数回文才有用)(造样例推一推和p数组的关系)。然后枚举以x,x+1为对称轴的双倍回文,检验是否存在(枚举y,看以y,y+1为对称轴且过x+1点的回文是否存在 ,显然y最大到x+f[x]/2,最小到x+1)
2017-07-28 21:21:35 378
原创 hdu4513 (manacher)
题意:求最长回文子串,且从最左到mid是单调不降的。基本同manacher板子,就加了一个条件:s[i+p[i]]#include #include #define N 100010inline int read(){ int x=0,f=1;char ch=getchar(); while(ch'9'){if(ch=='-') f=-1;ch=getchar();} wh
2017-07-26 21:14:47 456
原创 hdu3294 Girls' research(manacher)
manacher模板吧。。就多了个翻译一下输出串。#include #include #define N 200010char op[1],str[N],s[N<<1];int p[N<<1],n;inline int min(int x,int y){return x<y?x:y;}int main(){// freopen("a.in","r",stdin); wh
2017-07-26 18:00:06 311
原创 hdu3068 最长回文(manacher)
求最长回文子串,manacher模板题。就是充分利用已知信息,尽量减少冗余操作。因为mx是始终右移的,所以是O(n)的。#include #include #define N 110010char s[N<<1],str[N];int n,p[N<<1];//p[i]表示以s[i]为中心向一边延伸的最长长度(含i)//即s[i-p[i]+1]...s[i]=s[i]..s[i+p[i
2017-07-26 17:14:17 308
原创 CF 832D Misha, Grisha and Underground(Tree+lca)
题目大意:给你一棵树,n个节点。q个询问,给你a,b,c三个点,任意对应s,f,t,记s到f的路径为(s,f),让你求(s,f),(t,f)两条路径上的点的交集大小最大为多少。首先我们发现,对于给定的a,b,c,就三种情况即f=a,f=b,f=c.所以我们只需计算三次s,f,t,取最大即可。现在考虑对于给定的s,f,t,如何计算路径上的点的交集。设l1=lca(s,f),l2=lca(t,f),l
2017-07-26 13:30:18 412
原创 CF 86D Powerful array(莫队)
挺裸的莫队,然而我用lld输出T掉了???改成I64d输出就过了???有毒。#include #include #include #include #define ll long long#define N 200010int n,m,a[N],f[1000005],block;bool vis[N];ll ans=0,ANS[N];inline int read(){ i
2017-07-26 12:37:03 363
原创 poj2185 Milking Grid(二维KMP+最小覆盖矩阵)
题意:在字符矩阵中找出一个最小子矩阵,使其多次复制所得的矩阵包含原矩阵。首先我们计算答案矩阵的列数,叫做宽。对每行都计算出所有的重复子串可能的长度,如:AAAABAAA,可能的重复子串长度为:5,6,7,8.如何计算呢?k从m开始,每次k-fail[k]即为重复子串长度,k=fail[k],直到k=0.每行中都出现过的最小长度即为答案矩阵的宽。(遇到一个可能长度就计数器+1,最后从小到大扫一遍,次
2017-07-26 11:38:06 428
原创 hdu1841(KMP)
就是求包含两个给定串的最短串。那长度最长是len1+len2,如果有重叠的就减掉就最短了。拿s2匹配一次s1,再拿s1匹配一次s2,记录最大重叠。#include #include #define N 1000010int tst,fail[N];char s1[N],s2[N];inline int max(int x,int y){return x>y?x:y;}inline
2017-07-25 22:18:11 378
原创 hdu2594(KMP水题)
把俩串联在一起,用‘#’隔开,答案就是fail[n]#include #include #define N 50010char s[N<<1],s2[N];int n,fail[N<<1];inline void getfail(){ int k=0;fail[1]=0; for(int i=2;i<=n;++i){ while(k&&s[k+1]!=s[i]) k=fail
2017-07-25 21:47:23 345
原创 hdu3613 Best Reward(KMP)
本题难度在于判断回文前缀和回文后缀。我们设原串为s1,把原串翻转后得到的串记为s2.以s1为模式串去匹配s2,最后匹配到的位置我们记为k,k就是最长回文前缀长度。根据fail的性质,每一次fail[k]到的位置都满足前缀回文。那么我们就把这些回文前缀都标记了。回文后缀同理,我们以s2为模式串去匹配s1,那么k就是s2的最长回文前缀长度,即s1的最长回文后缀长度。同样处理,把这些回文后缀标记。然后我
2017-07-25 21:25:23 327
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人