随笔分类 -  动态规划

POJ-1141-完全加括号-DP
摘要:http://poj.org/problem?id=1141这是一道典型的动态规划题目,过去做过类似的,如POJ3391,思路几乎一摸一样,但是这道题目唯一比较讨厌的地方就是,得构造出最终的最优解,就是得显示出最优解的摸样,本来想通过做标记的方式,把DP的路径记录下来,后来感觉很麻烦,于是又加了一个bestStr[][]数组,元素类型是string,把每一个状态的形态记录了下来,bestStr[0][n-1]即是最优解,但是这样够早的话,可能附加操作比较多,因为每次都涉及很多字符串衔接的操作,导致最终居然超时。。。有时间,换一个方法实现以下好了,不用记忆搜索,换成循环递归实现以下,看看是否能摆 阅读全文
posted @ 2011-10-16 23:47 geeker 阅读(787) 评论(1) 推荐(1)
最长上升子序列 DP+贪心算法
摘要:最初没有多想,直接用最基本的DP写的代码,本想水过,可是测试数据超时。。。DP O(n*n)算法代码:#include<iostream>using namespace std;int main(){ const int SIZE = 1005; int dp[SIZE]; int arr[SIZE]; int n; while(cin>>n&&n!=0){ int max = 1; for(int i=1;i<=n;i++){ cin>>arr[i]; dp[i]=1; ... 阅读全文
posted @ 2011-10-10 00:57 geeker 阅读(574) 评论(0) 推荐(0)
POJ1159 回文数(DP基础题目)+POJ3991(类似题目)
摘要:http://poj.org/problemstatus?problem_id=1159这个题目即给定一个字符串,让你计算至少插入几个字母,就可将原字符串改为回文序列。设该字符串一共有n个字母,为str[1:n]状态dp[i][j]定义为:对于子串str[i:j]构成回文数需要插入字母数量的最小值。那么可知当头尾字母相同时,即str[i]=str[j]时,dp[i][j]=dp[i+1][j-1]如果头尾字母不想同时,那么可以在头部加一个和末尾一样的字母构成回文序列dp[i][j]=dp[i+1][j]+1 也可以在尾部加一个和头部一样的字母构成回文序列dp[i][j]=dp[i][j-1]+ 阅读全文
posted @ 2011-09-30 02:37 geeker 阅读(670) 评论(0) 推荐(0)
POJ 2084 递归+卡特兰数+JAVA大整数运算实例
摘要:POJ 2084 http://poj.org/problem?id=2084通过对题目的分析,总结出递归式:h(0)=1,h(1)=1 递归式:h(n)=h(0)*h(n-1)+h(1)*h(n-2)+...+h(n-1)h(0)(其中n>=2),这是n阶递推关系;然后第一次,用递归形式加记忆搜索写代码,不知怎么回事,时间特别慢,纳闷,之后又改为dp[]实际上,两者道理一摸一样,只是写法不同,可是写完后,发现此题得用高精度,吐血!!!然后想趁此题,把java的大整数运算的用法学会,否则,高精度虽然有模板,但是每次都得打一大堆代码,看的头都大了,,,《递归格式的代码》#include&l 阅读全文
posted @ 2011-05-19 16:16 geeker 阅读(652) 评论(0) 推荐(0)
POJ 2018 动态规划
摘要:http://poj.org/problem?id=2018题意很简单,就是给你N个数,让你求一个连续数串的平均值最大,连续数串的个数不得低于F个。那么就设dp[i],为以第i个数为最后一个数所能得到的最大平均值。那么dp[i]要在两种情形中选择最大值,第一种是基于dp[i-1],把第I个数作为前面串的末尾,第二种情况自己单独起一长度为F的串。代码如下:#include<iostream>using namespace std;const int NUM = 100001;int cows[NUM];int cowsum[NUM];//记录前F项之和,输入顺便打表,方便之后运算st 阅读全文
posted @ 2011-05-18 00:49 geeker 阅读(1180) 评论(7) 推荐(1)
POJ 1080 LCS 动态规划算发的变形
摘要:题目来源:POJ 1080 Human Gene Functionshttp://acm.pku.edu.cn/JudgeOnline/problem?id=1080解法类型:动态规划解题思路: 网上一份解题报告:写的很详细,就此摘来:http://nash250.blog.hexun.com/9794371_d.html和《算法导论》中动态规划章节的LCS(Longest common subsequence 最长公共子序列)所用例子基本是一样的,都是测两串基因的相似程度,不同之处在于《导论》用LCS表示两基因的相似程度,LCS越长,相似度越大。本题中用下面的核苷相近程度取值表表示两基因相似 阅读全文
posted @ 2011-05-11 17:35 geeker 阅读(568) 评论(0) 推荐(0)
POJ 1738
摘要:http://poj.org/problem?id=1738这题貌似是用DP可以搭,但是数据给的那么大,就不行了,写了个DP算法结果过不了,泪奔,哪位高手给指点下哦~~~而且根本就开不了50000*50000的数组啊,怎么办啊!!!#include<iostream>using namespace std;const int MAX = 50001;int dp[MAX][MAX];int piles[MAX];int n;int DP(int i,int j){ if(i==j){ dp[i][j]=0; return 0; } if(dp[i][j]) return dp[i] 阅读全文
posted @ 2011-05-05 19:02 geeker 阅读(507) 评论(0) 推荐(0)
POJ 1579 DP顺序控制不容易使,改为记忆搜索 !!!
摘要:http://poj.org/problem?id=1579很水的一道小题儿,一开始算dp[][][]的时候顺序随便按照i,j,k一次递增的顺序进行,后来发现不可以~而且每一个dp到底需要哪些之前的dp也不是很容易看出来,还是用递归的顺序加上记忆搜索就简化许多一开始的错误代码 :#include<iostream>using namespace std;int dp[21][21][21];int main(){ for(int i=0;i<=20;i++) for(int j=0;j<=20;j++) dp[0][i][j]=dp[i][0][j]=dp[i][j][ 阅读全文
posted @ 2011-05-04 01:47 geeker 阅读(189) 评论(0) 推荐(0)
POJ1887 DP水题儿
摘要:http://poj.org/problem?id=1887题目很基础,就是求 最长减子数列dp[i]=max{ max{dp[j]+1(arr[i]<arr[j] ; 1<=j<i )} , 1 }#include<iostream>using namespace std;const int MAX = 100000;int index;int dp[MAX];int arr[MAX];int main(){ int cin1; int t=1; while(scanf("%d",&cin1)&&cin1!=-1){ 阅读全文
posted @ 2011-05-04 00:57 geeker 阅读(304) 评论(0) 推荐(0)
POJ 1953 DP水题儿
摘要:http://poj.org/problem?id=1953用n个数字0或者1组成一个排列,要求每两个1不相邻,问有多少种排法dp[n][0]记录n个连续数,结尾为0的不同排列数dp[n][1]记录第n个连续数,结尾为1的不同排列数DP公式:dp[i][0]=dp[i-1][0]+dp[i-1][1];dp[i][1]=dp[i-1][0];#include<iostream>using namespace std;//dp[i][0]记录第i个连续数,结尾为0的个数//dp[i][1]记录第i个连续数,结尾为1的个数int dp[50][2];int main(){ dp[1][ 阅读全文
posted @ 2011-05-03 22:43 geeker 阅读(431) 评论(0) 推荐(0)
POJ 1050 最大子矩阵和 DP
摘要:1、首先考虑一维的最大子段和问题,给出一个序列a[0],a[1],a[2]...a[n],求出连续的一段,使其总和最大。a[i]表示第i个元素dp[i]表示以a[i]结尾的最大子段和dp[i] = max{a[i], dp[i-1] + a[i]}解释一下方程:如果dp[i-1] > 0,则 dp[i] = dp[i-1] + a[i]如果dp[i-1] < 0,则 dp[i] = a[i]因为不用记录位置信息,所以dp[]可以用一个变量dp代替:如果dp > 0,则dp += a[i]如果dp < 0,则dp = a[i]2、考虑二维的最大子矩阵问题我们可以利用矩阵压 阅读全文
posted @ 2011-05-02 21:36 geeker 阅读(1010) 评论(0) 推荐(0)
HDOJ 2577 How to Type 动态规划
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=2577设定两个记录数组,dp[i][0],dp[i][1],代表前i个字母所需要的最小按键数目。区别在于,dp[i][0]的情况是,w[i]这个字母(也就是最后一个)是在lock建关闭的情况下产生的最小数目。而dp[i][1]是在lock建打开的情况下产生的最小数目。因此分别考虑每种情况的dp公式char w[]数组记录字符串当w[i]为大写字母的时候,因为字母种类不是大写的就是小写字母,所以if(w[i]<=‘Z’)一句判断足矣。dp[i][0] = min(dp[i-1][0]+2,dp[i-1][ 阅读全文
posted @ 2011-05-02 21:05 geeker 阅读(393) 评论(0) 推荐(0)
HDOJ 2845 Beans DP
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=2845由于数据庞大,决不能直接DFS了,根据题目的特点,发现先对每一行DP,把每一行的最大值保存到一个数组中,再对这个数组DP一下,双重DP,不过用的同一个DP公式,挺有意思的~~~DP公式:dp[i]=max{dp[j](j<=i-2)}+w[i];#include<iostream>using namespace std;//dp1[]用来求出每一行的最大值,将最大值存入dp[2]中//最后再对dp2[]DP,就可求得整体最大值int dp1[200010],dp2[200010];// 阅读全文
posted @ 2011-04-29 00:40 geeker 阅读(243) 评论(0) 推荐(0)
记忆化搜索(附例题HDOJ 1501 )
摘要:记忆化搜索又称备忘录方法,是动态规划算法的变形。记忆化搜索编写形式就是直接递归形式,自顶向下,但是加上了标记放置重复搜索、而动态规划是通过打表的形式,自底向上比如过去写的一篇日志《矩阵连乘问题》http://www.cnblogs.com/liushang0419/archive/2011/04/27/2030970.html如果用递归形式实现的话,代码如下:但是仔细思考可以发现,直接用递归实现的话 1 int recurMatrixChain(int i,int j){ 2 if(i==j)return 0; 3 int u = recurMatrixChain(i,i)+recurMatr 阅读全文
posted @ 2011-04-28 13:09 geeker 阅读(2416) 评论(7) 推荐(3)
DP水题练习——HDOJ 2391 HDOJ1069 HDOJ 2512
摘要:HDOJ 2391http://acm.hdu.edu.cn/showproblem.php?pid=2391简单的DP dp[i][j] = max { dp[i-1][j], dp[i][j-1],dp[i-1][j-1] } + val[i][j];代码如下: 1 #include<iostream> 2 using namespace std; 3 int dp[1001][1001]; 4 #include<algorithm>//max()函数返回较大值 5 int main(){ 6 int t;cin>>t; 7 int m,n; 8 for 阅读全文
posted @ 2011-04-28 03:13 geeker 阅读(496) 评论(0) 推荐(0)
HDOJ 1024 M子段最大和问题
摘要:问题:给定由n个整数(可能为负整数)组成的序列e1,e2,…,en,以及一个正整数m,要求确定序列的m个不相交子段,使这m个子段的总和达到最大。分析:设b(i,j)表示数组e的前j项中i个子段和的最大值,且第i个子段含e[j](1£ i £m,i£ j £n)。以下称b(i, j)为“最后一个元素属于第i子段的j元素i子段问题”。则n个元素中求i个子段的最优值显然为:best(i, n) = Max{ b(i, j) } (i <= j <= n)计算b(i,j)的最优子结构为:b(i,j) = Max{ b(i, j-1) + e[j], 阅读全文
posted @ 2011-04-27 19:35 geeker 阅读(950) 评论(0) 推荐(0)