--------动态规划--------
Neo__Z
这个作者很懒,什么都没留下…
展开
-
NOIP2014 飞扬的小鸟 动态规划
解题报告:这道题很容易想出一个O(NM2)的动规 即f[i][j]表示飞到i列j高度位置需要的最小点击数,则 f[i][j]=minf[i−1][j−k∗x]+k,1≤k≤j/x(O(M))f[i][j]=min{f[i−1][j−k∗x]+k},1≤k≤j/x(O(M))(不考虑掉下来的情况)这显然会超时。仔细分析,我们可以发现i-1列的格子被计算了很多次,越下面的格子被算的次数越多到最下面时原创 2017-07-29 15:24:22 · 453 阅读 · 0 评论 -
NOIP模拟 Board
给出这样一棵“二叉树”:每个节点有左右两个儿子,并如下定义每个节点的高度:假设父亲节点的高度为 h ,那么他的两个儿子的节点的高度都是 h + 1 ,相同高度的所有节点称作一层。 每个节点的左儿子的子树都在右儿子的子树的左边,每一层相邻的两个节点之间有一条边。 下面是一个例子: 每一条图上的路径用一个字符串表示,字符串中的每一个字符表示一个移动。字符仅包含如下五种:1:表示移动到当前节点的左儿原创 2017-07-20 21:52:36 · 284 阅读 · 0 评论 -
NOIP模拟 table 动态规划
题目描述给定一个 n×m 的矩阵,行列均从 1 开始标号。一个矩阵被认为是稳定的,当且仅当对于任意的 2≤i≤n,第 i 行的数的和不小于第 i−1 行的数的和,且最后一行的数的和小于等于 m ,并且要求矩阵中所有的元素都是非负的。求所有 n×m 的稳定矩阵的方案数,答案对 109 取模。输入格式第一行一个整数 T ,表示数据组数。 每组数据一行两个整数 n,m 。输出格式输出 T 行,每行一个整原创 2017-07-20 21:36:33 · 355 阅读 · 0 评论 -
NOIP模拟 01祖玛【区间dp】
题目大意:给定一个初始只有黑白球的祖玛球串(01串),每次操作可向任意一个位置插入一个白色或黑色的球,三个以上连在一起的相同颜色的球可消去(有连锁反应,且初始串中无连续3个相同颜色的球),问消去所有球所需最少操作。输入样例4 11 10101 101001001 01001101011001100输出样例1 4 3 2解题思路:普通的祖玛是不符合最优子结构的,所以不能用动态规划原创 2017-10-17 18:21:12 · 482 阅读 · 0 评论 -
hdu1042 Max Sum Plus Plus【最大M子段和】
解题思路:题目中也没给m的范围,还O(n),结果只能O(nm)做。 dp[i][j]表示前j个数字分成i段,且a[j]在最后一段的最大和,那么转移方程为: dp[i][j]=max(dp[i][j-1]+a[j],max(dp[i-1][k])+a[j]),i≤\lej≤\len,i-1≤\lek<<j。 但这样时间空间都会超。 注意到dp[i]这一层只能由dp[i-1]一层转移,且max(原创 2017-10-18 10:47:02 · 277 阅读 · 0 评论 -
hdu 1421 搬寝室【动态规划】
解题思路:将物品按质量递增排序。 设dp[i][j]表示从前i件物品中拿走j对(j*2<=i)时最小疲劳值。 那么(1)不拿第i件,则dp[i][j]=dp[i-1][j],这个毫无疑问。(2)拿第i件物品,则第i件物品肯定和第i-1件物品一起拿最优,所以dp[i][j]=dp[i-2][j-1]+(w[i]-w[i-1])^2,即从前i-2件中拿j-1对的疲劳值加上拿了最后两件物品的疲劳值。原创 2017-10-18 16:47:40 · 326 阅读 · 0 评论 -
hdu1422 重温世界杯【动态规划】
解题思路:把环拆成2*n的序列,不断减去左边界,加上右边界更新即可。#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<queue>#include<vector>#define ll long longusing原创 2017-10-11 21:52:43 · 1158 阅读 · 1 评论 -
hdu1074 Doing Homework 【状压dp】
解题思路:就一个状态而言,我们需要知道所有作业是做了还是没做,再看看n≤\le15,所以可以用状压dp。用数字i的二进制表示每项作业做了还是没做。 定义dp[i]有三个域:mi,t,pre,分别表示i状态下最小扣分,对应的时间,和是从哪个状态转移来的(因为要输出方案)。 则dp[i].t=dp[j]+work[k].c,dp[i].mi=min(dp[j].mi+(dp[i].t-work[k]原创 2017-10-12 14:43:15 · 188 阅读 · 0 评论 -
hdu1503 Advanced Fruits【dp】【LCS】
题目大意:将两个字符串结合起来,他们的公共子串只输出一次解题思路:思路:根据LCS的原理,将每个状态从哪儿转移来的进行标记,然后回溯输出,其标记为公共子串的字符只输出一次即可,也是一道模板题了。#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmat原创 2017-10-11 07:47:24 · 386 阅读 · 0 评论 -
NOIP模拟 分玩具【博弈论】【动态规划】
题目描述豆豆和豆沙正在分一些玩具,每个玩具有一个好玩值,每个人可以拿走任意数量的玩具,获得的愉快度为最小的好玩值。现在豆豆先拿,每个人轮流操作,直到没有玩具可以拿。两人都按最优策略选玩具,豆豆想知道他能比豆沙多出多少愉快度?输入格式第一行 N 表示玩具个数。 接下来一行 N 个整数表示第 i 个玩具的好玩值。输出格式输出一个整数表示最多多出的愉快度。样例数据 1输入 [复制] 3 1 3 1原创 2017-10-11 16:58:00 · 366 阅读 · 0 评论 -
bzoj1084 最大子矩阵【轮廓线dp】
解题思路:虽说题目数据n≤\le100,k≤\le20,但其实可以用轮廓线O(kn)过。 m=1的情况就是最大M字段和问题,详见:http://blog.csdn.net/cdsszjj/article/details/78270332; 现在说m=2的情况,考虑dp覆盖部分边缘,共有四种情况: 分别记为0,1,2,3。 设f[i][j][k]表示用了i个矩阵,覆盖了j行,边缘情况为0,原创 2017-10-20 18:24:35 · 356 阅读 · 0 评论 -
hdu1502 Regular Words 【dp+高精度加法】
解题思路: f[a][b][c]表示用a个A,b个B,c个C的方案数,其转移方程为: if(b==0)f[a][b][c]=1; else if(c==0)f[a][b][c]=f[a-1][b][c]+f[a][b-1][c]; else f[a][b][c]=f[a-1][b][c]+f[a][b-1][c]+f[a][b][c-1]; 其中1≤\lea≤\len,0≤\leb≤\le原创 2017-10-10 21:36:23 · 317 阅读 · 0 评论 -
hdu3008 Warcraft 【动态规划】【背包问题】
解题思路:我们可以先算出被boss打死的时间m; 设f[i][j]为第i秒后剩余法力值j时对boss的伤害。 由于每秒法力值有回复且有上届,所以用i-1转移到i的方式比较难写,改用i转移到i+1。 转移方程为:f[i+1][x]=max(f[i][j]+c[k]),x=min(j-w[k]+t,100)。 可以将无法到达的状态跳过节省时间,不跳过也对,因为其不优。#include<iostr原创 2017-10-11 18:56:20 · 338 阅读 · 0 评论 -
hdu1501 zipper【记忆化搜索】【动态规划】
题目大意:给三个字符串A,B,C,问A和B能否按顺序组成C;解题思路:冲突关键在于如果C中某字符刚好都等于枚举到的A中字符和B中字符该怎么转移。法一:记忆化搜索。 dp[i][j]表示A枚举到i,B枚举到j时能否匹配成功。#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm原创 2017-10-11 20:37:04 · 320 阅读 · 0 评论 -
hdu1300 pearls 【dp】
题目大意:给定n种珠宝 每种珠宝两个数据,a[i]代表数量,p[i]代表单价 按 p[i]从小到大排。 购买珠宝时要满足以下购买规则: 单独买:每种珠宝要加上数量10 合并买:可以把连续几种珠宝数量合并,再加上10,单价按照price最大的计算 求出购买所有的珠宝最少要花费多少 解题思路:直接把a[i]合并为前缀和原创 2017-10-11 21:23:32 · 223 阅读 · 0 评论 -
hdu1224 Free DIY Tour【动态规划】
解题思路:动规方程:f[i]=max(f[j]+a[i]),有j到i的边。 输出方案可把每个点记一个前驱pre[i],回溯输出。 多组数据,注意清零,特别是a[n+1]=0。 最后一行不能再打空行,不然要PE。#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#i原创 2017-10-12 09:24:17 · 267 阅读 · 0 评论 -
bzoj1010 玩具装箱 【决策单调性优化dp】
算是一道模板题。 我们可以先得到朴素的dp方程:f[i]=min(f[j]+w(j,i)),j∈\in[0,i)。 w(j,i)表示将j+1~i打包运输的费用,时间复杂度为O(n2n^2)。 然后打表可发现满足决策单调性,所以就可以用单调队列维护决策点,二分查找每个点作为决策点的区间即可,时间复杂度为O(nlogn)。 不能在枚举时用直接判断j+1是否比j更优的方式移动决策点,如:f[0]=原创 2017-10-12 11:22:03 · 571 阅读 · 1 评论 -
hdu1080 Human Gene Functions【动态规划】
解题思路:f[ i ] [ j ] 表示匹配完第一条的第 i 个和第二条的第 j 个(均可以与空格进行匹配);① f [ i - 1 ] [ j ] + v (第一条第 i 个与空格匹配后增加的相似度) ,当该值大于 f 原值时就用它优化 f;② f [ i ] [ j - 1 ] + v (第二条第 j 个与空格匹配后增加的相似度) ,当该值大于 f 原值时就用它优化 f;③ f [ i - 1原创 2017-10-12 15:50:00 · 256 阅读 · 0 评论 -
hdu1059 Dividing 【多重背包】
解题思路:起初以为多重背包枚举状态会超时,但借鉴了别人的剪枝后就过了, 将价值从大到小枚举,那对于两个价值a1,a2(a1小于a2),当枚举同一级别的弹珠k时,若(a2-a1)%k==0,那a1+x个k可能会等于a2+y个k,而此后a1+z个k(z>x)就一定会等于a2+(y+(z-x))个k。若倒着枚举就可以break剪枝了。详见代码。#include<iostream>#include<cs原创 2017-10-12 17:15:14 · 237 阅读 · 0 评论 -
NOIP模拟 取书问题【概率期望dp】
题目描述:有n个同学坐成一列,按从前往后的顺序传n本书,第i本数是第i新的,其中第i个同学会从n-i+1本课本中选一本并把剩下的书传给后面的一位同学,第i个同学在挑选课本的时候满足 如下过程: 1.如果只剩一本书,则一定拿走,否则转步骤2; 2.从剩下的数中抽出最新的一本。 3.有a[i]的概率选择这本书并结束选择,1-a[i]个概率将这本书传给后面的同学并回到步骤1。 现在问最后一名同学拿原创 2017-11-08 08:33:13 · 439 阅读 · 0 评论 -
NOIP2016 T4 组合数问题
解题报告如果你知道Cji=Cji−1+Cj−1i−1C_i^j=C_{i-1}^j+C_{i-1}^{j-1},那这道题就是菜题了。 时间复杂度O(n2)O(n^2)#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>using name原创 2017-07-28 11:56:23 · 301 阅读 · 0 评论 -
NOIP模拟 Game 【博弈论】【动态规划】
题目大意:有n个物品排成一排,从左往右第i个价值为a[i],有两个人从左往右轮流取物品。第一个人可以拿一或两个物品。如果前一个人拿了k个,下一个人只能拿k或k+1个。如果剩下的物品不够拿,就结束。问如果大家都采取最优策略,那么先手拿的物品的价值最多能比后手多多少。(1≤\len≤\le20000)解题思路:设dp[i][k]表示从第i个物品开始先手拿k个后最多能比后手多取的价值,则: dp[i][原创 2017-10-30 18:15:15 · 671 阅读 · 0 评论 -
NOIP模拟 杆子的排列 【动态规划】
【题目描述】 有高为 1,2,…,n 的 n 根杆子排成一排,从左向右能看到 L 根,从右向左能看到 R 根。 求有多少种可能的排列方式。 【输入格式】 多组数据,第一行一个数 T,表示数据组数。 接下来 T 行,每行三个数 n,L,R,含义如题目描述。 【输出格式】 共 T 行,每行一个数,表示答案。答案可能很大,请对 998244353 取模。 【输入样例】 1 4 1 2原创 2017-10-22 20:42:49 · 410 阅读 · 0 评论 -
JZOI 3521 道路覆盖 二分答案+状压dp
解题报告:二分+DP 由于是求最小值中的最大值,所以二分答案ans,问题转化为了判定性问题。判定的方法是:每个位置都能到达高度ans的最小费用cost是否<=M。 注意到1<=K<=11,也就是说对于第i个路段,能够提高它高度的泥土只有从第i-K个到第i个。于是使用状态压缩动态规划求cost。f[i][j]表示前i个路段通过泥土使用>=高度ans,且第i - k个到第i个的使用情况为二进制数j的原创 2017-07-29 20:35:56 · 931 阅读 · 0 评论 -
hdu 2059 龟兔赛跑【动态规划】
解题思路:不妨把起点和终点都看做一个充电站。 设dp[i]是到第i个加油站所用最短时间。 则:dp[i]=min(dp[j]+t0,dp[j]+t1),0≤\lej<<i; 其中t0是不充电(全用脚蹬)从p[j]到p[i]所用时间,t1是充电从p[j]到p[i]所用时间。 为何没考虑从j不充电开始但还有剩余电量的情况呢?因为它可以看成从更前面一点充电开始所用时。 时间复杂度为O(n2n^2原创 2017-10-13 17:02:23 · 522 阅读 · 0 评论 -
hdu1081 To The Max 【动态规划】【最大子矩阵】
题目大意:给一个矩阵,求其最大子矩阵和。 其实只需要n2n^2枚举子矩阵高度i行至j行,再将每一列这部分求和,再求一维最大连续子序列就行了。 至于最大连续子序列,可以找我代码中那样做,也可以用最大前缀和减最小前缀和。#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>原创 2017-10-13 21:45:01 · 286 阅读 · 0 评论 -
bzoj 1030 文本生成器【AC自动机+dp】
解题思路:题目要求至少含有一个单词的方案数,可以转化成总方案数(26m26^m)减去不含有单词的方案数。 接下来把单词插到AC自动机上进行dp。 f[i][j]表示走到AC自动机的j号结点当前单词长度为i的方案数。 转移就是枚举下一位的26个字母,看是否可行(如果下一位在j的子节点中出现,若被标记为单词的结尾,就不能转移)。#include<iostream>#include<cstdio>原创 2017-11-10 09:46:04 · 302 阅读 · 0 评论 -
NOIP模拟 回文子串【动态规划】
题目大意:给定两个长度不超过50的大写字母字符串s,t,求他们的所有并字符串中的最长回文子串长度。 如:“CLEVER”和“JAVA”的一个并字符串为“CLJEAVVAER”,其最长回文子串为“EAVVAE”,长度为6。解题思路:考试时只想到四维dp就不知道怎么做了……蒟蒻。设想分别从两边开始取到中间合并。 设dp[l][r][L][R]表示表示s串从左往右取到s[l],从右往左取到s[r],t原创 2017-11-02 18:41:00 · 302 阅读 · 0 评论 -
NOIP模拟 赌博游戏【概率dp】
题目描述最近西雅图的高中校园里流行这样一个游戏。我们有一个骰子,这个骰子有M个面,分别写着1..M,并且是个公平的骰子,换句话说,一次投掷时每个面朝上的概率是相同的。游戏的组织者使用这个骰子进行N次投掷,并且告诉玩家点数v出现了至少一次。那么玩家需要猜测N次投掷的点数之和。如果猜对了,就赢得了这个游戏。小宇也喜欢玩这个游戏。在一次游戏中,她猜测了一个正整数sum,于是她想知道猜对的概率是多少。输入格原创 2017-11-02 18:51:33 · 1020 阅读 · 0 评论 -
NOIP模拟 边的处理【分治+动态规划】
题目描述有一个n个点的无向图,给出m条边,每条边的信息形如<x,y,c,r><x,y,c,r> 给出q组询问形如<u,v,l,r><u,v,l,r> 接下来解释询问以及边的意义。 询问表示,一开始你在点u上,然后按顺序处理编号从1到r的边。 对于一条边<x,y,c,r><x,y,c,r> ,你可以进行两次操作: 1、如果你当前在x点或者y点上,那么你可以走这条边(从x到y或从y到原创 2017-11-04 14:28:32 · 283 阅读 · 0 评论 -
NOIP2015 子串 【动态规划】
题目描述有两个仅包含小写英文字母的字符串 A 和 B 。现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一个新的字符串,请问有多少种方案可以使得这个新串与字符串 B 相等?注意:子串取出的位置不同也认为是不同的方案。输入格式第一行是三个正整数 n,m,k,分别表示字符串 A 的长度,字符串 B 的长度,以及问题描述中所提到的原创 2017-11-04 15:20:23 · 347 阅读 · 1 评论 -
bzoj1023 仙人掌图【仙人掌&&树形dp】
解题思路:f[i]表示以i为根的子树中i为起点的最长链。若(u,v)是桥,则ans=max(ans,f[u]+f[v]+1)(此时f[u]还未被f[v]更新),接着f[u]=max(f[u],f[v]+1);这也是树的直径的一种解法。若u是环上的一个点,设该环大小为cnt,则ans=max(ans,f[u]+f[v]+dis(u,v))其中v也为该环上一点且dis(u,v)<=cnt/2(不然就走环原创 2017-11-22 16:52:47 · 330 阅读 · 0 评论 -
bzoj1942 货币兑换【动态规划+CDQ分治】
解题思路:转自 www.cnblogs.com/zig-zag/archive/2013/04/24/3039418.html 稍稍加上个人见解(括号中)。经典的1D1D动态规划题目,标准做法是平衡树维护凸壳,但实际上还有更简洁的分治法。首先分析一下题目,对于任意一天,一定是贪心地买入所有货币或者卖出所有货币是最优的,因为有便宜我们就要尽量去占,有亏损就一点也不去碰。于是我们得到方程:f[i]=m原创 2017-12-19 21:24:37 · 450 阅读 · 0 评论 -
bzoj4559 成绩比较【动态规划+拉格朗日插值法】
解题思路:我们设f[i][j]f[i][j]表示前ii门课,共有jj个人没有被碾压的方案数,那么答案即为f[m][n−1−k]f[m][n-1-k]假设从f[i−1][w]转移到f[i][j](j≥w)f[i-1][w]转移到f[i][j](j\ge w) 没被碾压的人数本应增加Ri−1R_i-1人,但其中有一部分可能之前就没被碾压了。 则有t1=j−wt_1=j-w个人是新增的人数,要从n−1原创 2017-12-12 08:39:46 · 1045 阅读 · 0 评论 -
bzoj1597 土地购买【斜率优化dp】
解题思路:我们先将土地按xx值排序。 很容易得到一个O(n2)O(n^2)的dp方程: f[i]=min(f[j−1]+x[i]∗max(y[k]),1≤j≤i,j≤k≤if[i]=min(f[j-1]+x[i]*max(y[k]),1\le j\le i,j\le k \le i, 处理j时倒着循环,每次就可以O(1)得到max(y[k])max(y[k])了。其实我们可以把每块土地看做平面原创 2017-12-04 11:12:30 · 336 阅读 · 0 评论 -
bzoj1008 越狱【动态规划+快速幂】
解题思路:考虑用总方案数减去不会越狱的方案数。 设已有i个人且不会越狱的方案数为f[i]f[i],则再加一个人只需和第ii个不同即可,即是: f[i+1]=f[i]∗(m−1),且f[1]=mf[i+1]=f[i]*(m-1),且f[1]=m 快速幂即可。#include<cstdio>#define ll long longusing namespace std;const int p=原创 2017-12-04 15:56:47 · 235 阅读 · 0 评论 -
poj2068 Nim【博弈论】
题目大意:有2n个人,从0开始编号,按编号奇偶分为两队,循环轮流取一堆有m个石子的石堆,偶数队先手,每个人至少取1个,至多取w[i]个,取走最后一个石子的队伍输。问偶数队是否能赢。解题思路:设dp[i][j]表示轮到第i个人,还有j个石子的情况下他所属队伍是否能赢。 那么如果存在一个x,使第i个人取了x个石子后第(i+1)%2n个人无论如何都败,那么他就可以赢;若不存在则输。即是: dp[i][原创 2017-12-04 16:47:31 · 580 阅读 · 0 评论 -
bzoj4300 绝世好题【动态规划】
解题思路:注意只是bib_i&bi−1≠0b_{i-1}\ne 0,不是前缀与和为0。那么我们就可以按位dp,f[i]表示处理到当前数,第i位不为0的最优长度。转移就很轻松了,可以看代码。#include<bits/stdc++.h>#define ll long longusing namespace std;int getint(){ int i=0,f=1;char c;原创 2017-12-25 16:22:41 · 234 阅读 · 0 评论 -
poj2411 Mondriaan's Dream【插头dp】
题目大意:用1∗21*2的矩形铺满n∗mn*m的大矩形,问有多少种方案。1≤n,m≤111\le n,m\le 11解题思路:这道题所说可以用状压dp来做,但用轮廓线dp可以做到更优秀的复杂度。首先这道题只用考虑每段轮廓线上有无插头即可,按格转移,所以时间复杂度为O(n22n+1)O(n^22^{n+1})每个有以下四种情况: 分类讨论即可。轮廓线dp建议用滚动数组,这样换行的时候好转移。#i原创 2017-12-17 13:58:40 · 339 阅读 · 0 评论 -
bzoj1076 奖励关【期望+状压dp】
解题思路:若正着推,则一个状态会转移到两个状态,但我们不知道那一种更优,所以倒着推从两个状态转移到一个状态。设f[i][j]f[i][j]表示从第i轮j这个状态开始可以得到的最高分,那么初始状态为f[k+1][j]=0f[k+1][j]=0,我们要求的答案为f[1][0]f[1][0],转移方程如下:如果当前可以去第l个,则: f[i][s]+=max(f[i+1][s],f[i+1][s|(1<原创 2017-12-31 20:46:37 · 239 阅读 · 0 评论