随笔分类 -  DP

摘要:题意:乌拉尔锦标赛分为两轮,每轮有N道题,总共有2*N道题,但是在这些题中,有些题目有相似性,这样的题目是不允许放在同一轮里的,题目要求给出合理的题目分组来。分析:刚开始想用BFS搜的,在搜的过程中进行染色,但是最后放弃了这个思路,因为这个图极有可能是不连通的,怎样确定每个连通分支起始点的颜色才能找到一个合理的分组来就成为解题的关键,但是这个却没有一个准确的规律可循,所以只能用分组背包。其实就是先进行一遍dfs的深搜,将每个连通分支的点都分为两种颜色,将每个连通分支作为一组,然后进行dp求解。代码:View Code #include <stdio.h>#include <s 阅读全文
posted @ 2013-01-28 10:32 Misty_1 阅读(270) 评论(0) 推荐(0)
摘要:题意:给出n2个队伍,pij 表示队伍i能赢队伍j的概率,给出一个n2*n2个概率矩阵,让你求出最后总赢的可能性最大的队伍。思路:除了给出的矩阵里的数为double,这就是一个典型的dp题,不过中间要用到位运算,呃,这个真的好难理解。举个例子来说吧,n = 3 。(1) 1 2 3 4 5 6 7 8 (假设这一轮比赛后,获胜的队伍为 1 , 3 , 5 , 7 )(2) 1 3 5 7 (假设这一轮比赛后获胜的队伍是 1 , 5 )(3) 1 5 (这一轮比赛后获胜的队伍只能是 1 或 5 )所以,要想得出最后获胜的队伍,要比n轮,dp[i][j] 表示第i轮j获胜的概率,则,在第一轮... 阅读全文
posted @ 2012-08-20 21:16 Misty_1 阅读(145) 评论(0) 推荐(0)
摘要:题意:在M分钟里,每分钟会出现N颗龙珠,每颗龙珠的位置有题目给出,并且取走每个龙珠所消耗的能量也给出,同时在路上消耗的能量石|x1-x2|,如果在每分钟出现的龙珠里取一颗,问消耗能量最小是多少。思路:在比赛的时候就知道要有dp过,不过如果是不加优化的dp会超时的,所以要优化一下。先来推一下dp的状态转移公式。设dp[i][j]表示第i批龙珠中取第j个需要花费的最小体力。dp[i][j] = min{ dp[i-1][k] + abs(pos[i-1][k]-pos[i][j]) } + cost[i][j];如果直接用这个状态转移公式的,时间复杂度是:m*n*n,优化的话,如果每一个状态都看成 阅读全文
posted @ 2012-08-17 10:05 Misty_1 阅读(246) 评论(0) 推荐(0)
摘要:树形dp,顾名思义,就是在“树”的结构下用动态规划求最值。既然是在“树”形的结构下进行的,那么做这类题的第一步是先建树,然后顺着树的结构进行dp,一般从两个方向进行:1. 根—>叶:不过这种动态规划在实际的问题中运用的不多,也没有比较明显的例题。2. 叶->根:既根的子节点传递有用的信息给根,完后根得出最优解的过程。至于状态转移公式,这要具体题目具体分析。呃,来说说这道题。题意:各处含有N个节点的树,问你最少剪去几个边可以得到一颗包含P个节点的子树。思路:dp[i][j]表示以i为根的子树包含j个节点最少剪去的边,若j为1的话dp[i][1] 就等于i的子节点数,然后就是0-1背包 阅读全文
posted @ 2012-08-13 19:51 Misty_1 阅读(297) 评论(0) 推荐(0)
摘要:以前做过一道给定高度,然后给出长度让你求拼凑的方法的题,记得是到递推的题,如果这题不是在dp的训练计划里,我一定会耐心的去推公式的。呃,汗.......好吧,来说说这题吧。题意:给出矩形的长和高,然后让你计算用1*2或2*1的小矩形拼凑这个矩形,共有多少种方法?思路:刚才说了,开始我是想推公式来着,然后看了discuss了的一些讨论,才有了点想法,不过思路不是自己的,就不写了,个人觉得,下面这篇日志里讲的就很详细了~http://blog.csdn.net/wmn_wmn/article/details/7773167不过我觉得这题难的不是思路,而是关于二进制位运算的部分,如果不是很了解位运算 阅读全文
posted @ 2012-08-13 15:09 Misty_1 阅读(172) 评论(0) 推荐(0)
摘要:先说一下我了解的压缩状态dp吧。经典的压缩dp问题是TSP问题:一个n个点的带权的有向图,求一条路径,使得这条路经过每个点恰好一次,并且路径上边的权值和最小(或者最大)。或者求一条具有这样性质的回路。压缩dp问题中存储点集是利用二进制形式,比如 3 = 0000,0000,0000,0011 表示第一个和第二个点在点集中,5 = 0000,0000,0000,0101 表示第一个和第三个点在点集中,以此类推。呃,简单来说,就是用一个数表示一种状态,一般n<= 16 或n <= 32 。状态转移:如果状态存在,dp[i][j] = 0 ,否则为无穷大.1、状态存在:dp[i][j] 阅读全文
posted @ 2012-08-08 11:31 Misty_1 阅读(266) 评论(0) 推荐(0)
摘要:呃,一看到关于字符串的题就有点发怵,也不是完全因为字符串,而是对于处理字符串部署很擅长,偶尔错个小地方就要检查上半天,又是还不知道怎么错的,影响心情啊!!这题题意是:给出一个字符串,要你求出至少添加多少个字符可以是这个串成为回文穿串。大体思路:还是简单dp, dp[i][j] 表示从i到j至少要添加字符个数。转移方程有两种情况,一是如果str[i]== str[j] 的话,则dp[i][j]= dp[i+1][j-1] ;否则不想等的话,dp[i][j] = min ( dp[i+1][j] , dp[i][j-1] ) + 1 ;代码:#include <stdio.h>#inc 阅读全文
posted @ 2012-06-11 17:24 Misty_1 阅读(161) 评论(0) 推荐(0)
摘要:一道简单dp题,自己感觉这类dp题都很简单,只要找到一种状态,从小往大了推就行了,可关键是木读懂题啊。。。。。。开始读的时候,没认真理解where each soldier can see by looking lengthwise the line at least one of the line's extremity (left or right)这句话,结果理解成从一个用n个元素的数组中抽出几个数,使数组非递减或非递增排列,呃~自然WA的很惨,然后,看了题解,发现我错了,它是让找一个先上升在下降的最长序列,于是开始做,呃~有WA,因为漏掉了一种情况,1 , 2 , 3 , 4 阅读全文
posted @ 2012-06-10 10:48 Misty_1 阅读(161) 评论(0) 推荐(0)
摘要:最近在学习背包九讲,呃,现在刚看到多重背包问题,还是有点慢啊。这题是典型的多重背包问题,题意是,给你n中面值不同的纸币,每种面值为c,每种有n[i]张,给你一定的数额,问有这些纸币能组合出小于等于所给面值的最大钱数。但是题目中给的数据范围有点大,如果按基本的多重背包来做会TLE,看了《背包九讲》中利用二进制思想的优化,没看懂伪代码,搜了个代码慢慢研究,终于有点明白了,不过还是不明白为什么要按1 , 2, 4, ……2^(k-1) , n - 2^k 这样确定系数,呃,还是慢慢想吧~~代码:#include <stdio.h>#include <stdlib.h>#inc 阅读全文
posted @ 2012-06-07 20:02 Misty_1 阅读(189) 评论(0) 推荐(0)
摘要:题意:给你一架天平,C个挂钩位置和G个砝码,让你将这G个砝码全部用上,求有多少种方法使得天平平衡。思路:读完题后根本没有思路,如果让我自己想,我绝不会想到用dp做,但是这题是在背包问题的练习题里的,并且刚刚看完0-1背包,对dp有了一点理解,所以不难想到用dp做。可是,最后却在数组范围上卡了一下,想不明白为什么要开到15000,想了两天后,终于明白,力矩等于力臂*重量,而砝码的个数最多为20个,力臂最长为15,要使天平平衡的左右两边的重量为15*20*20 =7500,所以要开15000;代码:#include <stdio.h>#include <string.h># 阅读全文
posted @ 2012-06-05 20:11 Misty_1 阅读(190) 评论(0) 推荐(0)
摘要:最近在研究dp类的问题,正好前几天刷北航的时候看到了这题,当时觉得没什么,最长公共子序列在大一讲dp的时候就当做经典例题讲过,但是题目中要求用尽量小的空间,后来看0-1背包的时候看到讲0-1背包的空间优化,突然就想到这题了,于是拿来练练。。。。#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>#include <queue>#define maxx 1002using namespac 阅读全文
posted @ 2012-06-03 20:59 Misty_1 阅读(169) 评论(0) 推荐(0)
摘要:其实这题很水~但是通过做这题我终于知道了cin的输入有多慢了,以前做题总感觉自己很别人的思路一样怎么就慢了那么长时间呢,现在知道了,有一部分原因是有cin,cout输入输出的原因。这题用cin输入会超时,有scanf就ok了。其实这题就是一个递推公式,dp[i][j]=max(dp[i-1][j],max(dp[i-1][j-1],dp[i][j-1]));代码: 1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 int a[1002][1002]; 5 int max(int x 阅读全文
posted @ 2011-12-10 14:19 Misty_1 阅读(215) 评论(0) 推荐(0)
摘要:这就是一道简单的DP题,唯一的麻烦在于他要求输出起始点和终止点,用一个数组来存放起始点就OK了。代码: 1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 int main() 5 { 6 int a[100010],f[100010]; 7 int t,n,i,j,m,x,y; 8 scanf("%d",&t); 9 for(i=1;i<=t;i++)10 {11 scanf("%d",&n);12 for(j=1;j& 阅读全文
posted @ 2011-11-30 21:34 Misty_1 阅读(178) 评论(0) 推荐(0)