随笔分类 -  dp

背包问题(01背包、完全背包、部分背包)
摘要:之前写过一篇博客,这次看了下背包九讲,主要看的是部分背包的优化解法,转化的很巧妙,时间复杂度可以达到O(n*∑log(amount[i])*V),就是把原先每个背包的数量分成一堆一堆的。例如,假如物品i有14件,那么我们可以将它转化成若干个01背包问题,这几个子问题的背包价值和代价为1*price,1*cost,2*price,2*cost,4*price,4*cost, 7*price, 7*cost,这样我们总可以将1-13之内的数用这几个数来表示,一般的对于一个amout,我们只需要找到最大k,使得amout-2^(k+1) > 0. 这种优化方法,可以简单的这么理解,就是对于每一 阅读全文

posted @ 2012-10-10 16:18 buptLizer 阅读(3010) 评论(0) 推荐(1)

hdoj3001 travelling 状态dp tsp
摘要:题目意思:给出n个城市,每个节点允许至多访问2次,问访问所有城市1遍,最小的花费是多少?这个和tsp的区别就是每个城市可以访问2遍,思想一样,都是用一个位来表示当前状态,这个用三进制来表示,10个城市最大状态值为3^10 -1=59048。之前tsp是用dfs来递归搜索的,这次正向扩展状态,思想都是一样的dp[i][st]表示到达城市i状态为st的值,我们的目前就是求最小的dp[i][st],并且st满足没有未访问的城市。转移方程为:dp[j][st] = min{dp[j][st], dp[i][prest]+road[i][j]},这里需要满足限制条件,就是prest中第i位不能为2,因为 阅读全文

posted @ 2012-08-24 21:52 buptLizer 阅读(378) 评论(0) 推荐(0)

poj1185 炮兵阵地 经典状态压缩dp
摘要:这个题目和上一个种玉米的是一个类型,都是状态dp,用二进制位来表示当前的一个状态值,只不过比上一个稍微复杂了一点,需要用三维的数组来保存当前state。题目:在一个N*M的矩阵上布置炮兵部队,只有平原可以布置,然后每个炮兵部队都有一个攻击范围,它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。问:如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队?由于是求的最多能放置的炮兵个数,就是求某一个状态下,它对应的炮兵个数最多,所以就想到dp方程肯定是那种dp[i+1]= 阅读全文

posted @ 2012-08-23 09:33 buptLizer 阅读(4698) 评论(0) 推荐(0)

poj3254 Corn Fields(状态dp)
摘要:状态dp一般就是用二进制位来表示当前状态,本质还是动态规划,所以要找到转移方程,一般dp需要满足的就是最优子结构、无后效性,状态dp可能加入了一些位运算,加快程序的执行。题目大意:给出一个M*N的矩阵,元素为0表示这个地方不能种玉米,为1表示这个地方能种玉米,现在规定所种的玉米不能相邻,即每行或者没列不能有相邻的玉米,问一共有多少种种植方法。举个例子:2 31 1 10 1 0表示2*3的玉米地,现在一共有多少种种植方法呢? 答案:种0个玉米(算一个合法方案)+种1个玉米(4)+种2个玉米(3)+种3个玉米(1)=9我们分析每一行种植玉米的状态其实之和前一行的种植状态有关系,和它前面的其余行没 阅读全文

posted @ 2012-08-22 13:44 buptLizer 阅读(2253) 评论(0) 推荐(0)

poj2411 Mondriaan's Dream 棋盘覆盖
摘要:问题描述:给出一个n*m的棋盘,及一个小的矩形1*2,问用这个小的矩形将这个大的棋盘覆盖有多少种方法。由于我们放置小矩形的时候可以横着放也可以竖着放,那么就会产生不同的方法,但是必须满足不产生空的未覆盖的空格子。首先我们用二进制1 0表示在某一个问题放置或者不放置,那么有m列的棋盘,每一行有2*m个状态了,我们现在就找出每行之间的规律。对于一个矩形有3种方法:横放,竖放,不放。由于第i行只跟第i-1行的放置有关系,因为我们必须保证第i-1行使放满的,现在用dp[i][state]表示第i行状态为state的方法,那么dp[i][curstate]=sum{dp[i-1][prestate]}. 阅读全文

posted @ 2011-10-16 18:00 buptLizer 阅读(1745) 评论(0) 推荐(0)

背包问题
摘要:1 01背包问题有N件物品和一个容量为V的背包。(每种物品均只有一件)第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。解法:我们用dp[i][j]表示前i件物品重量不超过j的最大价值,则dp方程为j>w[i]时,dp[i][j]=max{dp[i-1][j],dp[i-1][j-w[i]]+c[i]}j<=w[i]时,dp[i][j]=dp[i-1][j].其中dp[i-1][j]表示第i件物品无法放在背包里的价值,dp[i-1][j-w[i]]+c[i]表示第i件物品放入背包里的最大价值,我们选择其中的较大的。优化:采用一维数组来优化dp[v] 阅读全文

posted @ 2011-10-15 21:39 buptLizer 阅读(332) 评论(0) 推荐(0)

最大子序列问题小结
该文被密码保护。

posted @ 2011-09-26 18:58 buptLizer 阅读(47) 评论(0) 推荐(0)

poj1738 an old stone game
摘要:石子合并,经典dp,我们定义dp[i][j]表示从i开始的j个石子合并的最小(最大)代价,dp方程为:dp[i][j]=min{dp[i][k]+dp[i+k][j-k]+sum[i][j]},sum[i][j]表示从i开始的j个数的和。这个题目由于规模太大了,无法开一个5000*5000的数组,需要用到其他方法,discuss里面说用Garsia Wachs算法,没听说过,有待研究。下面的是我处理小规模的dp代码:#include #include using namespace std;const int INF=1000000001;const int N = 500;int m[N], 阅读全文

posted @ 2011-09-09 12:00 buptLizer 阅读(636) 评论(0) 推荐(0)

poj3034 Whac-a-Mole (dp)
摘要:打地鼠游戏,dp好题,麻烦的不是写出dp方程,而是求出从(x1,y1)到(x2,y2)这条直线上经过那些整数坐标,利用gcd求出来,并且需要知道的一点是中间的某个点可能跑出到矩形外面,处理跑出矩形外地点只需要扩大范围就行了,行列各增加10,让冒出地鼠的坐标响应的+5即可,dp[t][x][y]表示时刻t坐标xy出得最大个数,那么此状态可能是由上一个状态dp[t-1[i][j]转移过来的,其中(i,j)和(x,y)距离<=d,我们去所有可能的ij中的最优值,代码如下:#include <iostream>#include <cmath>#include <st 阅读全文

posted @ 2011-09-08 15:01 buptLizer 阅读(410) 评论(0) 推荐(0)

poj3624Charm Bracelet 01背包
摘要:经典动态规划题目,这个题目最开始用的书本的思想,用m[i][j]表示前i件物品重量不超过j的最大价值,则dp方程为:m[i+1][j]=max(m[i][j-w[i+1]]+p[i+1],m[i][j]),也就是从i+1件物品中得到重量不超过j的最大价值的时候,第i+1件要么选要么不选,但是这个题目由于w和n比较大,这么会MLE,所以必须缩小空间,由于m[i][j]只和当前i的重量和价值有关系,对于当前的物品我们要么选要么不选,我们直接用一维数组表示 dp[j]=max(dp[j-w[i]]+p[i],dp[j])。计算的时候要从后往前计算。代码:#include <iostream&g 阅读全文

posted @ 2011-09-07 21:40 buptLizer 阅读(165) 评论(0) 推荐(0)

导航