动态规划
文章平均质量分 70
omsobliga
这个作者很懒,什么都没留下…
展开
-
10012 How Big Is It?(****)
/*题意:一堆小球,要求使用最小的矩形将它们全部装起来。要求小球必须接地,至少与其他一个小球相邻思路:涉及到状态转移,用到动态规划思想。原来通过深搜,剪枝结果WA,后来想到两个相邻小球半径相差很大的情况,于是没有了做题思路。看别人代码后,搜索中添加两个数组,A[i]表示第i个小球的半径大小,c[i]表示第i个小球排完后右边界最远的位置。于是有状态转移方程: c[i]=max(c[j]+2*原创 2012-03-02 22:36:53 · 587 阅读 · 0 评论 -
HDU 1003 最长字段和(经典动态规划)
//原来做这道题,使用刘汝佳书上的方法实现,动态规划来做,很经典的一道题#include const int nMax = 100007;struct Node{ int l, r; int sum; Node(){} Node(int l, int r, int sum):l(l), r(r), sum(sum){}}node[nMax];int main(){原创 2012-09-05 19:14:38 · 1174 阅读 · 0 评论 -
POJ 1157 LITTLE SHOP OF FLOWERS(动态规划)
/*题意:每行选一个数,下一行选得数只能在这一行后面,求选出所有数的最大和。很容易的一道题,原来只使用了一个数组d[],结果运算中出现很多情况,而且最后发现思路根本就是错误然后增加一个数组d1[],问题变得很容易。状态转移方程:d[i][j] = max(d[i - 1][k] + map[i][j]),i - 1 <= k < j;d[i][j]表示加入只有i行,第i行必须选择第j列时原创 2012-09-05 20:13:22 · 645 阅读 · 0 评论 -
POJ 1088 滑雪(动态规划+记忆化搜索)
//动态规划 + 记忆化搜索#include #include const int nMax = 107;int R, C;int map[nMax][nMax];int dp[nMax][nMax];int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};int fdp(int x, int y){ if(dp[x][y] != 0) ret原创 2012-09-05 19:09:34 · 822 阅读 · 0 评论 -
POJ 2353 Ministry(双向DP)
/*题意:矩形M*N,要求:只能向下、向左、向右走,求从第一层到最后一层费用最小的路径。思路:双向DP(其实就是两个for循环),因为最佳路径只有三种从上、从左、从右,所以只需要三个循环即可原来使用Dijskra中寻找最短路径的方法,果断超时!*/#include #include const int mMax = 107;const int nMax = 507;int m原创 2012-09-06 16:52:59 · 1275 阅读 · 1 评论 -
POJ 2486 Apple Tree(树形DP + 01背包)
/*树形DP + 01背包思路:首先bfs将图转变为树,然后dfs进行动态规划。有两种状态,其中d[0][i][j]表示直通,d[1][i][j]表示返回到i节点①、②处,曾经出错临界状态的初始化,始终感觉是个难点,一直没有搞清楚。最后在测试数据1 11的时候发现问题。*/#include #include const int nMax = 107;const int mM原创 2012-09-08 21:24:50 · 615 阅读 · 0 评论 -
动态规划总结
学习动态规划有一段时间了,总结一下,开始新的算法一、为什么要使用动态规划?当回溯效率太低的时候,动态规划是个不错的选择,因为它是不断建立在最优状态上的递推,得出最终结果。二、动态规划两大标志:1)最优子结构:一个问题的最优解包含子问题的最优解,这个性质被称为最优子结构2)重叠子问题:不同问题包含相同的子问题。即:原问题不断分解成同样的子问题,而不是产生新的问题。重点:重叠子原创 2012-05-02 21:26:44 · 832 阅读 · 0 评论 -
HDOJ 1024 Max Sum Plus Plus 最大K段子序列和(01背包 + 滑动数组 + 优化)
/*/*超时。题意:输出m个子序列和的最大值思路:动态规划 + 滑动数组d[m][j] = max(d[m][j - 1] + e[j], max(d[m - 1][k] + e[j]) | k ∈ [m -1, j)).表示前j个序列分割成m组,最大序列和因为状态方程中只用到d[m]和d[m - 1]两个状态,所以只需要一个二维数组即可。优化:至于max(d[m - 1][k原创 2012-08-07 15:36:59 · 982 阅读 · 0 评论 -
POJ 1947 Rebuilding Roads(树形DP + 01背包)
/*01背包(最小价值) + 树形DP,做的第一道树形DP问题思路:d[i][j]:以i为跟的树,选j个节点,根必选原来一直Runtime Error,最后发现①处的问题,漏了N*/#include #include const int nMax = 157;const int INF = 0x3fffffff;int next[nMax];int head[nMax];in原创 2012-09-08 21:43:27 · 629 阅读 · 0 评论 -
POJ 2411 Mondriaan's Dream(状态压缩)
/*正常求解超时,然后打表通过。自己定义状态,我的解法横木块[0,0],竖木块[1,0],其中1表示下层。也可以横木块[0,0],竖木块[1,2],不过会多出一个状态,需要3进制表示。*///打表程序#include #include __int64 h, w;__int64 d[11][1 << 11];__int64 check1(__int64 x)//相连的0必须为原创 2012-09-13 10:31:09 · 982 阅读 · 0 评论 -
HDOJ 4276 The Ghost Blows Light(最短路+树形DP)鬼吹灯问题
/*参考:http://nightelf.sinaapp.com/2012/hdu-4276.html鬼吹灯问题题意:每个坟墓都有一些珠宝,从一个坟墓到另一个坟墓需要耗费掉一定的时间,问从1到N,在规定时间T内,最多可以得到珠宝数思路:最短路+树形DP,找出从1到N的最短路,因为任何两点间只有一条路,所以最短路中所有边都为必走的边。所以从1到N的路径,都为最短路,然后加上从最短路中某些个原创 2012-09-11 20:40:38 · 1120 阅读 · 0 评论 -
POJ 1185 炮兵阵地(状态压缩)
/*推荐:经典状态压缩我原来四进制表示,结果果断超时!解题关键:假设一行所有列均为P,将所有可行状态,存储到数组A[]中,经过计算,状态最多有60种,然后再进行DP。否则很容易超时。d[i][j][k]:表示第i-1行状态为j,第i行状态为k,最大炮兵数。如果只是d[i][j],则无法从前面状态推导,虽然前两行状态可以知道,但会存在冲突。而d[i][j][k]则可有效避免,因为前两行原创 2012-09-12 20:57:26 · 551 阅读 · 0 评论 -
HDOJ 4271 Find Black Hand(最短编辑距离)
/*A一道题,真心觉得不容易,各种情况要考虑。不过是一道经典DP问题首先这道题,是一道最短编辑路径问题,很久以前做过这类问题,一直没做了,所以看到这道题时候根本没有往DP方面想。d[i][j]表示,母串ss[i]得到子串s[j]的最小编辑次数,并且i与前面的操作相连。然后这道题,可以出现环,具体处理将母串复制一遍添加到后面。但是同一个字母不能用多次,所以需要分情况处理。比如母串:abcd原创 2012-09-15 21:41:57 · 1073 阅读 · 1 评论 -
HDU 4293 Groups(区间DP)
/*具体思路参见:http://hi.baidu.com/dispossessed/item/320544233e27109b9c63d1a6将每组数据转换为区间以后,然后按照x从小到大排序,便可以用DP来做。注意不符合条件的排除,①处的作用*/#include #include #include const int nMax = 507;int d[nMax];int N;原创 2012-09-20 22:51:03 · 690 阅读 · 0 评论 -
HDU 4283 You Are the One(区间DP)
/*这道题才真正接触到区间DP的思想d[i][j]:表示从第i个到到第j个人的最小值,那么第i个人可以是第一个出,也可以是最后一个出,假设是第k个出,则区间可分为[i + 1, i + 1 + k - 1 - 1],d[i + k, j]前者肯定是在k之前出,后者在k之后,于是转换为区间DP问题其中需要对后者做一下处理,加上(k - 1) * (sum[j] - s[i + k - 1])原创 2012-09-21 20:25:05 · 814 阅读 · 0 评论 -
HDU 1421 搬寝室
/*状态转移方程:d[i][j] = min(d[i][j - 1], d[i - 1][j - 2] + (A[j] - A[j - 1]) * (A[j] - A[j - 1]))d[i][j]:表示前j个物品搬运i次最小的疲劳度*/#include #include using namespace std;const int nMax = 2002;const int I原创 2012-08-18 19:50:16 · 581 阅读 · 0 评论 -
hdoj 1011 Starship Troopers(树状DP)
/*这道题还不错,四星题意:N个洞,M个士兵,每个洞中有a个bug,b个brain,每个士兵可以处理20个bug,入口在洞口1处,问可以得到多少个brain。思路:0-1背包问题状态方程:d[a][b] = max(d[a][b - k] + d[j][k]),其中a、j之间有边相连。d[a][b]表示以a为根节点的子树,包含b个士兵,所能得到最大brain。按a来分层进行动态规划。原创 2012-08-07 00:52:59 · 2183 阅读 · 0 评论 -
103 - Stacking Boxes
/*题意:矩形嵌套类型,不过是多维,要求输入k个n维图形,求可嵌套个数最大的一组,输出最大个数和字典序最小的那一组。一次AC,典型动态规划题。*///#define TEST#include #include #include bool map[35][35];int d[35],box[35][15];int next[35],ans[35];int k,n;int cm原创 2012-04-26 14:30:03 · 404 阅读 · 0 评论 -
116 - Unidirectional TSP
/*题不难,不过做的时候状态没有考虑清楚,所以耗时很大。出发和结尾无限制,字典序越小越好。重点注意:状态是二维的,所以要是做存储结构时,也要注意必须使用二维数组,否则会冲掉一些数据。题意:旅行商问题,从第一列走到最后一列,耗时最少需要怎么走,走法受限制,第一行和最后一行相邻。*///#define TEST#include #include const int nMax=107原创 2012-04-26 15:16:59 · 584 阅读 · 0 评论 -
10405 Longest Common Subsequence
/*最长公共子序列问题,一次AC。简单题,找出状态转移即可题意:一串字母,求最长子序列字母个数(只需要字母先对顺序一样即可,不需要连在一起)思路:if(line[x1]==line[x2]) d(x1,x2)=d(x1+1,x2+1)+1;else d(x1,x2)=max(d(x1,x2+1),d(x1+1,x2));*///非递归实现#include #include原创 2012-04-26 15:41:22 · 587 阅读 · 0 评论 -
348 - Optimal Array Multiplication Sequence
/*典型动态规划题型,一次AC题意:矩阵相乘,要求输出运算次数最少的运算式思路:以第k个乘号为一个状态,状态方程:d(x1,x2)={max(d(x1,k)+d(k+1,x2)+x1*k*x2)|k属于[x1,x2)}使用数组ans[x1][x2]存储相应的k值,最后使用递归输出!*/#include #include const int nMax=15;long long原创 2012-04-26 17:00:29 · 573 阅读 · 0 评论 -
10304 Optimal Binary Search Tree
/*最优搜索二叉树,典型动态规划题,AC搜索二叉树首先满足二叉树中序遍历是自小变大的,最优搜索二叉树则要求每个节点的路径长和它出现的概率之积的和最小。最优搜索二叉树的左子树和右子树必须也是最优搜索二叉树,否则根据“剪贴”原理,还能找到一个比现在二叉树更优的一颗二叉树所以可以得到状态转移方程:f[i][j]=min{f[i][k-1]+f[k+1][j]+sum(i,j)-a[k] | k原创 2012-04-30 16:43:02 · 958 阅读 · 0 评论 -
11258 String Partition(最大int型)
/*推荐题型:四星,原来不会做!最大int型问题,总感觉这类问题中用到了一些估算。因为有些步骤想不清楚状态d[i]表示,到i为止,所组成的最大整数状态转移方程为:d[i]=max{d[k]+sum(k+1,i) | k<i}注意:如果用到了不常用的数类型,如:long long,很容易会有遗漏,要多注意。*///#define TEST#include #include原创 2012-04-30 23:33:36 · 626 阅读 · 0 评论 -
10069 - Distinct Subsequences(高精度+动态规划)
/*强力推荐:五星,WA!!!首先要用到高精度处理。动态规划的使用这里有点小问题,原来我的想法,d[i][j]表示line1从i和line2从j开始的不同子序列个数。d[i][j]=sum{d[i+1][k] | k属于(j,len2)}。状态有len1*len2种,状态转移有len2种。另一种解法:d[i][j]=d[i][j+1];if(line1[i]==line2[j]) d[原创 2012-04-30 13:33:52 · 753 阅读 · 0 评论 -
11151 - Longest Palindrome
/*简单题求最长回文数,多阶段决策问题类动态规划题意:字符串S中包含的最长回文数为多长。即删除若干个字母后,剩余为回文数,问长度最长为多少。状态转移方程为:if(str[i]==str[j]) f[i][j]=f[i+1][j-1]+2;else f[i][j]=max(f[i+1][j],f[i][j-1]).*///#define TEST#include #incl原创 2012-04-30 20:28:11 · 711 阅读 · 0 评论 -
10453 - Make Palindrome
/*推荐:四星。这道题做得时候有些害怕,没有仔细去想。小感悟:动态规划题,试着去分析各个状态之间的联系,记住:去本上画出几个状态找其中的联系。这是关键,然后写出状态转移方程。注意:①处,因为将==误写成了=,导致WA了N多次,一直找不到原因,因为测试结果始终正确。题意:将字符串补全为回文数,问最少添加几个字母即可。*/#include #include const in原创 2012-05-01 10:17:25 · 840 阅读 · 0 评论 -
集合上的动态规划---最优配对问题(推荐:*****)
/*提醒推荐:五星刘汝佳《算法竞赛入门经典》,集合上的动态规划---最优配对问题题意:空间里有n个点P0,P1,...,Pn-1,你的任务是把它们配成n/2对(n是偶数),使得每个点恰好在一个点对中。所有点对中两点的距离之和应尽量小。状态:d(i,S)表示把前i个点中,位于集合S中的元素两两配对的最小距离和状态转移方程为:d(i,S)=min{|PiPj|+d(i-1,S-{i}-原创 2012-05-01 21:54:01 · 5407 阅读 · 7 评论 -
POJ 2411 Mondriaan's Dream(DP---状态压缩)
/*推荐:五星动态规划、状态压缩、dfs题意:m*n矩形,要求使用2*1的小块矩形进行填充,共存在多少种方法。解题思路:使用1、0对每一格进行填充,首先考虑只有两行,则存在三种情况:竖着放置第i行为1,第i+1行为0;横着放置第i行为11,第i+1行为11;第i行正好为上一行竖着放置凸出来的部分,则第i行为0,所以下面一行肯定为1。使用d[i][s]表示第i行为状态s时的最大放置方原创 2012-05-02 16:35:54 · 733 阅读 · 0 评论 -
108 Maximum Sum
/*推荐题型:四星。 动态规划题意:输入矩形长度N,矩形中节点上的数值A[i][j],输出子矩形所包含节点的数值之和的最大值。动态规划策略:状态:d[lx][ly][rx][ry]表示矩形(lx,ly,rx,ry)中的最大值。状态转移方程:d[lx][ly][rx][ry]=max(d[lx+1][ly][rx][ry],d[lx][ly+1][rx][ry],d[lx][ly原创 2012-05-09 23:47:54 · 677 阅读 · 0 评论 -
动态规划---状态压缩(即集合上的动态规划)
参考博客:http://godfrey90.iteye.com/blog/725562一、首先谈谈什么是状态压缩?状态压缩就是将一个阶段或(集合)的状态使用二进制0、1进行表示,这类问题中,状态只存在两种:有或无。通过二进制来达到节省存储空间和查找效率的作用。二、什么是动态规划?动态规划是通过定义某一个状态,这个状态可以通过性质相同的另一个(或多个)状态推导出来,即存在最优原创 2012-05-02 16:04:59 · 2034 阅读 · 0 评论 -
poj 3254---Corn Fields
/*状态压缩+动态规划题意:M*N的一块地,进行划分,要求划分后各区域不能有公共边,可以一块也不选择。题意我也不懂,根据后面所给的测试数据,才有了一些了解。思路:状态:d[i][s]表示第i行状态为s时所有的方案数。状态转移:d[i][a]=sum(d[i-1][b]),a、b的关系为a中为1的位置b为0;a的判断有两个条件:①与图进行匹配,图中为0的位置不能为1②两个1不能相连原创 2012-05-02 20:35:57 · 718 阅读 · 0 评论 -
HDU 4295 4 substrings problem(状态压缩)
/*内存超了,这道题原来不想做,后来打算只要把数据过了就行结果内存超了,状态压缩,具体思路参见:http://acmicpc.info/archives/915*/#include #include const int INF = 4100;int d1[4096][16][64], d2[4100][16][64];char S[4100], a[4][70];int can原创 2012-09-21 12:29:57 · 965 阅读 · 0 评论