随笔分类 -  DP

摘要:这一题综合了DFS和DP,很好的一道题。dp[i][j]表示以第i行第j列个网格为起点所能得到的最大值,需要注意的是一次最多走k步必须在一条直线上,这个只需要在普通的深搜上加一层循环表示从1步到k步,状态转移就是dp[i][j] = max{dp[i + d1*c][j + d2*c], 1=< c <= k} + map[i][j]。AC code:View Code 1 #include<iostream> 2 using namespace std; 3 4 int a[101][101]; 5 int dp[101][101]; //dp[i][j]表示从位置( 阅读全文
posted @ 2012-03-28 18:56 背着超人飞 阅读(298) 评论(2) 推荐(0)
摘要:初看起来貌似没什么思路,后来慢慢发现这题原来就是数塔问题的变形啊,还是用dp做,只不过将时间看作是行,将位置看做是列。状态转移方程为:f[i][j] = get_max(f[i + 1][j], f[i + 1][j + 1], f[i + 1][j - 1]) + a[i][j].由于位置有0-10共11个,所以在记录数据的时候记成1-11比较方便,防止数组越界。AC code:View Code 1 #include <iostream> 2 #define MAX 100001 3 using namespace std; 4 int Hash[MAX][20];//用二维数 阅读全文
posted @ 2012-03-27 16:27 背着超人飞 阅读(371) 评论(0) 推荐(1)
摘要:这一题算是一道典型的裸睡(又裸又水)题了吧,不过用刚学的滚动数组进行了优化,时间跟空间复杂度大幅度下降,如果字符长度超过5000的话恐怕不进行优化是要MLE的,不多说了,看代码吧。。。状态f[i][j]表示检查到Ai跟Bj时的最长公共子序列的长度,如果Ai = Bj,那么f[i][j] = f[i - 1][j - 1] + 1,否则考虑三种情况:(1)Ai在公共子序列中,Bj不在, f[i][j - 1];(2)Bi在公共子序列中,Ai不在, f[i - 1][j];(3)Ai跟Bi都不在,f[i - 1][j - 1]。由于第三种情况一定小于前两种情况,故f[i][j] = max{f.. 阅读全文
posted @ 2012-03-06 16:54 背着超人飞 阅读(180) 评论(0) 推荐(0)
摘要:这一题的思路就是先求出原序列与原序列的逆序列的最大公共子序列的长度,然后用原序列的长度减去即可。至于为什么这样做还请高手指点。。。因为题目中的数据量比较大,开5000*5000的数组会MLT,所以考虑用滚动数组来做。。。状态f[i][j]表示检测的Ai与Bj时的最大公共子序列的长度,状态转移方程为:f[i][j] = max{f[i - 1][j], f[i][j - 1]} + 1。。。AC code:View Code 1 #include <iostream> 2 #define MAX 5001 3 using namespace std; 4 int maxlen[2][ 阅读全文
posted @ 2012-03-06 16:14 背着超人飞 阅读(144) 评论(0) 推荐(0)
摘要:这一题就是典型的动态规划,从数塔的底部开始用dp[i][j]表示到第i行第i个数的时候数塔的最大值,转移方程为dp[i][j] = dp[i][j] + max{dp[i + 1][j], dp[i + 1][j + 1]}, 显然最后结果为dp[1][1]。AC code: 1 #include <iostream> 2 #define MAX 500 3 using namespace std; 4 int n; 5 int tri[MAX][MAX]; 6 int d[MAX][MAX]; 7 8 void input() 9 {10 for(int i = 1; i < 阅读全文
posted @ 2012-03-04 22:57 背着超人飞 阅读(127) 评论(0) 推荐(0)
摘要:这一题就是将一维的最大字段和扩展到二维,在一维的求最大字段和的过程中是这样操作的:int max_sum(int n){ int i, j, sum = 0, max = -10000; for(i = 1; i <= n; i++) { if(sum < 0) sum = 0; sum += a[i]; if(sum > max) max = sum; } return sum;}扩展到二维的时候也是同样的方法,不过需要将二维压缩成一维,所以我们要将数据做一下处理,使得map[... 阅读全文
posted @ 2012-03-04 22:41 背着超人飞 阅读(1612) 评论(1) 推荐(2)
摘要:这一题是比较简单的动态规划,状态f[i]表示走前i个棋子时的最高分数,状态转移方程为f[i] = {max(f[j]), i > j && step[i] > step[j] + step[i]}.AC code: 1 ude <iostream> 2 #define MAX 1000 3 using namespace std; 4 5 int step[MAX]; 6 int f[MAX]; 7 int n; 8 int max_sum(int i) 9 {10 int max = 0;11 int j;12 for(j = 0; j < i; 阅读全文
posted @ 2012-03-01 21:50 背着超人飞 阅读(255) 评论(0) 推荐(0)
摘要:题目大意是找到一个最多的老鼠序列,使得序列中的老鼠的体重满足递增,相应老鼠的速度满足递减。思路就是先按体重递增进行sort排序,然后按照体重找到最长递减子序列即可,用动态规划做比较简单。状态f[i]表示前i个老鼠中的最长递减子序列长度,状态转移方程为f[i] = max{f[j], mice[j].speed > mice[i].speed} + 1, 最后找出最大的f[i]即可。注意此题还需要输出找到的序列中的老鼠的最原始的标号,因此不仅要在刚开始的时候把每个老鼠的最初的序号记下来,还要在进行状态转移的时候把当前的老鼠的位置标记下来。AC code: 1 #include <io 阅读全文
posted @ 2012-03-01 21:10 背着超人飞 阅读(345) 评论(0) 推荐(0)