随笔分类 - 动态规划
摘要:问题:在一个给定的区间[a,b]内,找满足要求的数。如果我们用暴力的话一般要考虑数的大小,而数位dp要考虑的确实数的组成。例如: 递增的 1234 1357 2468 整除13的 13 26 39 包含13的 132 2134 双峰的 152630 243052如果数的位数大于100,暴力肯定Over。数位dp要注意的就是数的组成处理以及数的边界处理。核心思路:记忆化搜索+记录合适状态。数位dp顾名思义就是逐位dp逐位考虑。举例: [0,8457]内逐位递增的数有多少个。那么我们先对第一位进行处理,即枚举0XXX,1XXX,...8XXX。当我们枚举到第二位的时候。0...
阅读全文
摘要:题意:数列A1,A2,...,AN,修改最少的数字,使得数列严格单调递增。(1=b-a,这样才能满足夹在中间的数能够修改。那么本题在nlogn求最长上升子序列的基础做一些处理即可。处于满足的序列中必须有a[i]-lis[x]-1>=i-pos[x]-1,并且替换的时候不是原来的找到大于这个值的最小的,而是找满足前面这个式子已求序列中最大的。比如序列:1 3 6 6 13 2 8 9 10,求最长上升子序列过程中当求得的序列为 1 3 6 13 时,当遇见8时,我们不是变为1 3 6 8,而是变成1 3 8, 因为只有这样才是满足条件的,当时它的最长序列top=4不会变化。还要注意的一点是
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4632题意:给你一个序列,问你该序列中有多少个回文串子序列,可以不连续。思路:dp[i][j]表示序列i到j中具有的回文串序列数。 当s[i]==s[j], dp[i][j]=dp[i+1][j]+dp[i][j-1]+1 否则dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]; 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespa...
阅读全文
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=2196题意:有n台电脑相连,让你求每台电脑与离它最远的那台电脑的距离。思路:两遍搜索即可,第一遍从上到下,第二遍从小往上。对于某点,该点的最长半径为此点离自己孩子的最大距离和父亲节点传递下来的最长距离加连接此点的权值,两者之间选择最大值,但这里处理的时候要注意了,某点的孩子距离和父亲传递下来的最大距离可能为同一路径,因为父亲节点的最大距离可能经过此点。所以在处理的过程中不仅要随时记录最长路径,还要记录一个次长路径。这里WA了几次,更新最长路径的时候,记得要提前把最长路径传递给次长路径。讲的很绕口。 1 #in
阅读全文
摘要:题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=27623#problem/D题目大意:给你一串字符串,在满足第一个回文串右边小于第二个回文串左边的情况下,能组成多少个回文串。解题思路:个人感觉是一道不错的dp题,先预处理出所有的f[i][j],f[i][j]表示i到j是否是一个回文串。这里比较巧妙的利用到一点dp,如果字符i等于字符j,那么 f[i][j]=f[i+1][j-1]。然后再预处理出前i个字符能组成的回文串数,再求解。这题开始没考虑清楚,我是枚举所有分界点,处理两边的字串,出问题了,因为这样会重复处理.....
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401题目大意:现在要你去炒股,给你每天的开盘价值,每股买入价值为ap,卖出价值为bp,每天最多买as股,最多卖出bs股,并且要求两次买卖必须间隔W天,问你在T天内如何进行炒股操作从而获得最大收益。解题思路:先吐槽一下,会单调队列但不会dp不行,会dp但不会单调队列也不行!!开始dp动态转移方程倒是写对了,然后算算时间复杂度T*T*Maxp*Maxp,优化不得当,一直以为是dp思路错了,囧。 对于有单调队列参与dp的题,dp方程必须准确先写好,然后再观察可否用单调队列。 dp[i][j]...
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4291题目大意:g(0) = 0,g(1) = 1,g(n) = 3g(n - 1) + g(n - 2),给你一个n(0<=n<=10^18),求g(g(g(n))) mod (109+ 7)。解题思路:如果直接利用n做三次矩阵快速幂求解的话,无奈的WA了。因为三次快速幂对1000000007取模的话,超精度了。所以必须本地处理寻找每层的循环节,最外层最1000000007取模,则找到最外层的循环节是222222224,次外层对222222224取模,找到次外层循环节是183120。接
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1227题目大意:有n个餐馆和k个仓库,每个餐馆都要有一个仓库负责送货,每个仓库可以送货给多个餐馆,仓库可以放在任意餐馆的位置,问你哪个仓库给那些餐馆送货能使总的送货距离最小。解题思路: dp[i][k]表示前i个餐馆需要k个仓库送货,假设i,j餐馆之间需要设一个仓库,日常联想就可知道设在i,j的"中间"即是最小值了,dp[i][k]可由状态dp[j][k-1]个状态更新而来,dp[j][k-1]表示的是前j个餐馆(j<i)需要k-1个仓库,还要加上第个j+1餐馆-->
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1005题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=35381005题目大意:告诉你f[1]=1, f[2]=1, f[n]=(A*f[n-1]+B*f[n-2])%7;然后输入A,B,n,让你求f[n]。解题思路:解法1:n比较大,给你这样递推式子一般不可能让你全部求出来,一般是有规律可寻的。只要在递推的过程中发现f[n-1]==f[1],f[n]==f[2],停止递推。把它多少个数循环一次记录下来,然后只需要用
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1257题目链接:1257解题思路: 一开始一直纠结在求最小下降的次数(从大减少到最小的的为一次)。 想了很久才恍然大悟,这题可以转换成求最长非降子序列。贪心思想。 1 http://acm.hdu.edu.cn/showproblem.php?pid=1257#include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <algorithm> 5 #include <c
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1114题目大意:给你一个体积为V的猪猪存钱罐,然后有一些体积为c,价值为w的硬币,问你如何装硬币能使总价值最大。解题思路: 这题有两点错误很容易犯。 第一:用了01背包而不是完全背包。 第二:初始化问题还没搞清楚(这里的初始化指的是不同类型的最大值初始化的条件不一样)1、题目给你的硬币数量没规定只能取一次,能取多次当然就是完全背包了,当然也有可能是多重背包,这里不讨论。2、重点在第二点了。背包进行初始化时,如果恰好完全装满,则dp[0]赋值为0,其余赋值为无穷。如果只希望价值最大,则初始化时将dp[
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1058(1058) http://acm.hdu.edu.cn/showproblem.php?pid=3199(3199)题目大意:给你四个素数2,3,5,7,只由它们四个组成合数,对这些合数从大到小进行排列,求第n个合数的大小。解题思路: 一看到这题,开始想要暴力,从1到Max进行横扫遍历,ok这题暴力没问题1171ms,因为题目给了限制n最大只有5842,如果我给的数很大呢,比如n=100000,暴力明显TLE。 所以这题我们要换种思路,因为题目只给了4个数(如果题目...
阅读全文
摘要:题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1260题目大意:有n个数1—n,将他们排成一列。最左边必须是1,后面排列的数字和与他们它们相邻的数字只差不能超过2,求有多少中排列方式。解题思路:一开始看到这题,才55个点,果断dfs,结果TLE。不过至少答案是正确的,然后把答案给记录起来,仔细一分析,发现有规律可寻,打表,果断过了。规律递推式:dp[n]=dp[n-1]+dp[n-3]+1。搜狗一下发现别人此题写的是DP,囧。然后又思考了一下,果然如此。n个人时求dp[n]。第2个位置放2时有dp[n-1]种;第2个位置放3,第3个
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3127题目大意:一个大矩形,要你分割成小矩形(只能水平和竖直切割),每个小矩形都有一个价值,问如何分割能得到最大总价值。解题思路:完全背包思想,枚举所有可能情况。对于枚举每个小矩形都可以横放竖放两种情况。对于每种情况都有两种切割方式:横向切割或者竖向切割。 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using names
阅读全文