动态规划
文章平均质量分 50
冰阔落
Stay hungry, Stay foolish, Stop when you are perfect.
展开
-
UVA - 10599 Robots(II)
题目大意:有一个row * col的矩阵,然后给出若干个坐标,代表该坐标上有垃圾,现在有一个机器人,支持向下以及向右的移动,每次移动到一个位置,可以将该位置上的垃圾清理掉,要求求出从(1,1)的位置到(row, col)最多能收多少垃圾,以及有多少条路线可以收最多的垃圾,并输出路径。解题思路:因为机器人只支持向右和向下,也就是说对于横纵坐标来说是递增的,所以可以转移成LIS的问题去求解原创 2015-03-16 20:09:21 · 1458 阅读 · 0 评论 -
UVA - 10913 Walking on a Grid
题目大意:给出n,k,然后给出一个n*n的图,从(1,1)通过向下,左和右三个方向,走到(n,n)点,途中不可以走相同的位置,并且路过的位置为负数的个数impossible解题思路:记忆化搜索,用四维数组去记录最优解,vis二维数组表示当前访问状态,dp[x][y][i][j]表示位置x,y的地方,当路过的负数个数为i且从j代表的方向进入时的最优解。我写完的时候超时了,但是原创 2015-03-16 20:01:57 · 1380 阅读 · 0 评论 -
UVA - 10604 Chemical Reaction
题目大意:给出n和m,有n种化学药剂,型号由1~n,然后给出n * n行代表相应的两种化学药剂反应后的生成物以及释放的热量,然后给出m个试管,每种试管中有对应的药剂,要求将m种药剂反应合成一种,不要求反应后药剂的种类,要求反应所散发的热量最少。注意:i和j反应可能与j和i反应不同,反应可能吸热,每组测试以/结束。解题思路:开一个cnt数组记录每种药剂的数量,然后用递归的方法原创 2015-03-16 19:58:57 · 1810 阅读 · 0 评论 -
UVA - 607 Scheduling Lectures
题目大意:给出课题数n,以及每堂课的时间l,以及常数c,然后是n个课题所需要的时间。问题1:最少需要几节课时可以讲所有的课题讲完,并且课题的顺序不能调换,一个课题不能分在两节课讲。问题2:在用的课时最少的情况下,如何让同学们的不满意度最低,不满意度的计算是根据课时的剩余时间t计算的,解题思路:问题1可以用贪心的方法, 问题2用记忆化搜索。#include #i原创 2015-03-16 19:58:50 · 1506 阅读 · 0 评论 -
UVA - 10401 Injured Queen Problem
题目大意:给出一个字符串,要求在n * n(n为字符串的长度)的棋盘上摆放n个受伤的皇后,受伤的皇后只能攻击到同一列和它周围8个格子,如果字符串中第i个字符为'?'表示第i + 1个皇后可以摆放在任意行,如果为1 ~ F表示第i+1个皇后必须摆放在第str[i]行, 问,有多少种不同的摆法?解题思路:一开始用递归 + 记忆化, 结果超时了, 后来发现其实可以写成递推,dp[i][j]代原创 2015-03-16 19:45:26 · 1412 阅读 · 0 评论 -
UVA - 10313 Pay the Price
题目大意:有0~300这300种价值的金额。 现在可能给出参数:1个:n, 输出可以组成价值n的方式的个数。2个:n, a输出用个数小于a的价值组成价值n的方式的个数。3个:n, a, b输出用个数大于a和小于b组成价值n的方式的个数。解题思路:完全背包的问题, 状态转移方程dp[i][j] 表示价值i用j个硬币组成的方式种类, 转移方程dp[j][k] += dp[j原创 2015-03-16 19:43:53 · 1547 阅读 · 0 评论 -
UVA - 825 Walking on the Safe Side
题目大意:给出n,m,现在给出n行数据, 每行有k(k为不定值)个数字, 第一个数字代表行数, 后面k - 1个数代表当前行的这个位置不可走, 问有多少路径可以从(1,1)到(n,m),只能向下或向右。解题思路:dp[i][j] = dip[i - 1][j] + dp[i][j - 1], 很简单的dp问题。#include #include #include #inclu原创 2015-03-16 20:22:18 · 1577 阅读 · 0 评论 -
UVA - 11008 Antimatter Ray Clearcutting
题目大意:有一篇森林,给出n棵树的坐标,现在有一种反物质光线,可以清楚直线上的树木,然后给出m,代表这片森林要除掉m棵树,问最少使用几次光线。解题思路:状态压缩,要用位运算去做,下面介绍一篇写的比较好的题解。http://www.cnblogs.com/scau20110726/archive/2012/09/28/2707866.html#include #原创 2015-03-16 20:04:37 · 1434 阅读 · 0 评论 -
UVA - 10626 Buying Coke
题目大意:给出要买可乐的数量, 以及1元,5元和10元硬币的数量, 每瓶可乐8元,每次照钱会按照最少硬币的方式找回, 问如何投币可使得投入的硬币数最少, 输出最少硬币值。解题思路:记忆化搜索, 因为可乐每购买一次便要找会硬币,所以对与每个状态考虑的情况比并不是很多。注意:1、每够买一次可乐便会找回一次硬币,所以不用考虑的太复杂。2、题目中虽然说1元不超过500个,但是开原创 2015-03-16 19:55:26 · 1522 阅读 · 0 评论 -
UVA - 10029 Edit Step Ladders
题目大意:给出若干个按照字典序排列的字符串,每两个字符串之间可以存在一个梯度,也可不存在,所谓梯度就是指前一个字符串同过改变、删除或填加一个字符,是转化后的字符串等于后面一个字符串,问,在所给出的若干个字符串中最多能连续通过梯度连接多少个字符串,输出最大值。解题思路:类似与LIS,可是用o(n^2)的算法却超时, 可以用二分的方法在前面的字符串中找匹配,给出的字符串是按照字典序排列的,原创 2015-03-16 19:39:31 · 1488 阅读 · 0 评论 -
UVA - 10465 Homer Simpson
题目大意:有两种汉堡包, 给出吃汉堡的时间, 再给出总的时间, 尽量不浪费给出的时间,输出能最多吃的汉堡个数, 如果一定需要浪费时间, 输出浪费时间最少的时刻内能吃的最多汉堡个数, 并再后面输出浪费掉的时间。解题思路:因为汉堡可以无限制的使用, 所以相当于是完全背包问题,dp[i]就是代表在i分钟之内最多能吃多少汉堡(时间完全使用完), dp[i] = 0说明该时间是有浪费的。原创 2015-03-16 20:25:52 · 1531 阅读 · 0 评论 -
VA - 10651 Pebble Solitaire
题目大意:给出一个12格的棋盘,‘o'代表摆放棋子,’-‘代表没有棋子, 当满足’-oo'时, 最右边的棋子可以跳到最左边的位子,而中间的棋子则被消除,‘o--', 问对于一个给定了的棋盘,通过上述消除棋子的方法最后最少剩几个棋子在棋盘上。解题思路:递归搜索 + 记忆化, 并且记忆化的值为所有测试数据公用的,也就是说在程序运行的开始初始化后,后面无需再进行清0。#includ原创 2015-03-16 20:25:18 · 1489 阅读 · 0 评论 -
UVA - 10163 Storage Keepers
题目大意:给出m为仓库的数量, 给出n为有守夜人的数量, 然后给出n个数值,为对应守夜人应付的酬劳,每个守夜人的能力与他需要的酬劳是相等的,并且守夜人可以同时负责多个仓库的安全,不过这样子安全值就变为val[i]/k(val[i]表示第i个守夜人的能力值,k表示他负责的仓库数量, /为取整),先在要的出方案,使得所有仓库中安全值最低的那个仓库的安全值越高, 并且要使得酬劳越低。解题思路原创 2015-03-16 20:09:26 · 1468 阅读 · 0 评论 -
UVA - 10201 Adventures in Moving - Part IV
题目大意:有n个测试数据组, 对于每个测试组,最先给出一个距离lenth, 然后给出若干个加油站的位置以及加油站每升油的价钱。然后有量油桶容量为200升的卡车,出距离为0的位置开始移动向lenth,每升油可以使的卡车走一个单位距离,问,卡车到达lenth的时候,并且油箱中仍有100升油,最少花费多少钱,如果不能到达,输出“Impossible”。解题思路:用递推的方法,对每个加油站进行原创 2015-03-16 19:29:49 · 1512 阅读 · 0 评论 -
UVA - 10285 Longest Run on a Snowboard
题目大意:在一块R * C的雪地上有个叫name名字的人滑雪, 每次可以从高的地方滑向低的地方, 现在要选一个地方开始滑雪, 要求可以滑动的距离最长, 输出最长值。解题思路:可以说是DFS吧, 但是对于每个位置只遍历一次, 然后记录最优解, 下次再遇到时可直接调用最优解。#include #include using namespace std;int H[10100];原创 2015-03-16 20:13:33 · 1515 阅读 · 0 评论 -
HDU - 2602 Bone Collector
题目大意: 一个叫做Bone Collector的男的有一个包,往包里放东西,使得其价值最大。解题思路:01背包#include <cstdio>#include <algorithm>using namespace std;int main() { int T; scanf("%d", &T); while (T--) { int N, V, A[1原创 2015-08-21 16:52:46 · 1773 阅读 · 0 评论 -
UVA - 1456 Cellular Network
题目大意:手机在蜂窝网络中的定位是一个基本问题。假设蜂窝网络已经得知手机处于c1, c2,…,cn这些区域中的一个,最简单的方法是同时在这些区域中寻找手机。但这样做很浪费带宽。由于蜂窝网络中可以得知手机在这不同区域中的概率,因此一个折中的方法就是把这些区域分成w组,然后依次访问。比如,已知手机可能位于5个区域中,概率分别为0.3、0.05、0.1、0.3和0.25,w=2,则一种方法是先同时访问{c原创 2015-08-10 20:25:20 · 1772 阅读 · 0 评论 -
UVA - 1442 Cav
题目大意:一个洞穴的宽度为n(n解题思路:设每个片段中燃料的高度为l,初始值为是s[0]或s[n-1],如果当前片段的地面高度pi>l,则l=pi,顶高度si#include #include using namespace std;int n, p[1000010], s[1000010], h[1000010];int main() { int Z; sc原创 2015-08-09 18:19:48 · 1937 阅读 · 0 评论 -
UVA - 1422 Processor
题目大意:有N个任务,每个任务只能在开始时间到结束时间之内完成有任务量。完成所需时间是w / 处理器速度。输出处理器速度最大值的最小值。解题思路: 一秒一秒来算。建一个优先队列,结束时间越短越优先,因为要最快完成。一秒内能处理的任务量就是处理器的速度mid。出队,如果能处理完就减掉,不能处理完就减一下任务量,因为任务还木有完成,所以还得入队。一直重复,直到全部都出队。#include <cstdi原创 2015-07-14 21:35:10 · 1641 阅读 · 0 评论 -
UVA - 1394 And Then There Was One
题目大意:给出n,k和m,表示有n个人围成一个圈,从第m个人开始(m也要去掉),每次走k步删除掉,问最后剩下人的序号。解题思路: 数学递推 分析: 1 题目是一道变形的约瑟夫环变形问题 2 网上看到一篇很好的数学递推法 问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。编号0-(n-1)是有意义的,因为要模n,所以用0-(原创 2015-07-14 16:31:43 · 1615 阅读 · 0 评论 -
UVA 1292-Strategic game
题目大意:给出一棵树,在某个选择某个结点可以覆盖和它相连的所有边,问最少选多少个结点所有边都被覆盖。 解题思路:首先将无根树转化为有根树,0为根。 用d[i][0]表示不选择结点i时覆盖以结点i为根的子树最少要多少个结点,用d[i][1]表示选择结点i时覆盖以结点i为根的子树最少要多少个结点。若结点i不选,为了和覆盖所有和结点i相连的结点,则每个儿子都必须选,若结点i选,则每个儿子选择较小的那个原创 2015-05-19 22:08:14 · 1569 阅读 · 0 评论 -
UVA - 1220 Party at Hali-Bula
题目大意:n 个人形成一个关系树,每个节点代表一个人,节点的根表示这个人的唯一的直接上司,只有根没有上司。要求选取一部分人出来,使得每 2 个人之间不能有直接的上下级的关系, 求最多能选多少个人出来,并且求出获得最大人数的选人方案是否唯一。 解题思路:分析发现是要求一个树的最大独立集。这里可以用树形 DP 解决。定义dp【x】【0】:表示在 i 点不选 i 点的以 x 为子树的最大独立集 而dp原创 2015-05-18 19:20:16 · 1482 阅读 · 0 评论 -
ZOJ - 3201 Tree of Tree
题目大意:给一棵节点带权的树,找到一个有k个节点的子树,求这个子树的最大权值 解题思路:树形 DP + 背包,f(i, j) 表示以i为根节点的有j个节点子树的最大权值,然后对i的每个子节点做分组背包,因为对于i的每个儿子,可以选择分 1,2,3…j-1 个节点给它f(i, j) = max{ max{f(i, j-p) + f(v, p) | 1 <= p < j} | v是i的儿子节点} a原创 2015-05-18 21:33:57 · 1610 阅读 · 0 评论 -
HDU 1081 To The Max
题目大意:给一个n^2矩阵 求一个和最大的子矩阵解题思路:动态规划求最大子矩阵和,把二维的转化为一维的就好做了。 1、首先看一维数组 a[] 求最大字段和,b记录以i结尾的数组最大字段和;显然若b否则b+=a[i]; 2、转化为一维的数组就是枚举某一连续几行,把每一列的值加起来存到 一个元素中, 这些元素就构成了一个一维数组。 然后原创 2015-04-14 19:47:17 · 1519 阅读 · 0 评论 -
UVA - 10404 Bachet's Game
题目大意:由一堆石子, 给出石子的总数, 接下来由stan和ollie两个人玩游戏,给出n, 在给出n种取石子的方法(即为每次可取走石子的数量),由stan先,两人轮流取走石子,最后一个将石子全部去完的人胜利,问, 给出的一堆石子, 两人均按最好的方案游戏, 最后将会是谁胜 ?解题思路:问题可以看做是一个完全背包的变形, dp[i]只有0 和1两种状态, 1 是代表当前i个石子先取原创 2015-03-16 20:17:38 · 1598 阅读 · 0 评论 -
UVA - 10118 Free Candies
题目大意:给出三个字符串,从分别从第一个字符串和第二个字符串中挑选子串a,b,用a和b组成第三个字符串,问可组成的子串有多少种。解题思路:dp[i][j][k]表是用s1中的前i个字符和s2中的前j个字符的子串组成s3前k个字符的情况。仿照http://www.cnblogs.com/yuzhaoxin/archive/2012/05/04/2483259.html#inc原创 2015-03-16 19:54:56 · 1548 阅读 · 0 评论 -
UVA - 10534 Wavio Sequence
题目大意:给出一个字符串, 找出一个奇数的子序列,子序列的前版部分要递增, 后半部分要递减, 且递增和递减的长度要相等, 要求输出最长满足条件的子序列的长度。解题思路:题目可以转化成求字符串的最长递增子序列, 正向求一遍, 反向求一遍, 然后将相应位置的最长值取最小的进行比较(min(a[i], b[n - i - 1]), 因为要求递增部分和递减部分的长度要求相等, 但是长的部分可以原创 2015-03-16 20:21:53 · 1432 阅读 · 0 评论 -
UVA - 10154 Weights and Measures
#include #include #include using namespace std;struct T { int w; int s;} A[5610];int cmp (T a, T b) { return a.s < b.s;}int main() { int n, DP[5610], cur; memset(DP, 0x3f3f3f3f, sizeof原创 2014-11-23 18:21:21 · 1599 阅读 · 0 评论 -
UVA - 10051 Tower of Cubes
#include int main() { char S[6][10] = {"front", "left", "top", "back", "right", "bottom"}; int n, T = 0, cube[505][6], next[505][6][2]; while (scanf("%d", &n), n) { for (int i = 0; i < n; i++)原创 2014-11-21 16:50:02 · 1560 阅读 · 0 评论 -
UVA - 10130 SuperSale
题目大意:有n件物品, 每件物品有它的价值和重量, 然后对于每一个测试数组有m个人,每个人有可承受的最大重量, 现在要求在每个人的承受范围内尽量使得价值最大, 然后对于物品来说有无数多个, 但是对于每个人来说, 不可以重复拿同一件物品。解题思路:01背包的问题, 将每个人看成是一个背包问题, 求m个人的最有解就是要求的答案了。#include int main() {原创 2014-11-23 00:42:29 · 1733 阅读 · 0 评论 -
UVA - 357 Let Me Count The Ways
#include int main() { long long n, M[5] = {1, 5, 10, 25, 50}, DP[30005] = {0}; DP[0] = 1; for (int i = 0; i < 5; i++) { for (int j = M[i]; j < 30005 ; j++) if (DP[j-M[i]]) DP[j] += DP[j-原创 2014-11-22 11:55:54 · 1622 阅读 · 0 评论 -
UVA - 674 Coin Change
题目大意:有5种硬币, 面值分别为1、5、10、25、50,现在给出金额,问可以用多少种方式组成该面值解题思路:每种硬币都有无限个,所以是典型的完全背包,但是这一题的数据 n 最大到30000那么如果一直累加中间过程和是会超过int,所以我们必须用long long ,其它还要注意方案数为1的时候输出比较不同原创 2014-11-22 19:02:01 · 1638 阅读 · 0 评论 -
UVA - 437 The Tower of Babylon
#include #include using namespace std;struct Node { int x; int y; int h;} P[100];int cmp(Node a, Node b) { return a.x != b.x ? a.x < b.x : a.y < b.y;}int main() { int n, a[3], T = 0; w原创 2014-11-19 15:59:41 · 1611 阅读 · 0 评论 -
UVA - 10131 Is Bigger Smarter?
#include #include using namespace std;struct Node { int w, s; int order, next;} E[1005] = {0};int cmp(Node a, Node b) { return a.w != b.w ? a.w b.s;}int main() { int n, DP[1005]; for原创 2014-11-18 23:11:05 · 1462 阅读 · 0 评论 -
UVA - 531 Compromise
#include #include using namespace std;int main() { string A[105], B[105], V[105]; while (cin >> A[0]) { int DP[105][105] = {0}; int n = 0, m = 0, cnt = 0; while (A[n] != "#") cin >> A[原创 2014-11-15 16:42:10 · 1476 阅读 · 0 评论 -
UVA - 111 History Grading
#include using namespace std;int main() { int n, temp, A[25], B[25], DP[25][25] = {0}; cin >> n; for (int i = 1; i <= n; i++) { cin >> temp; A[temp] = i; } while (cin >> temp) { B[temp]原创 2014-11-14 16:30:49 · 1542 阅读 · 0 评论 -
UVA - 11151 Longest Palindrome
#include #include #include using namespace std;int main() { int T; scanf("%d%*c", &T); char A[1005]; while (T--) { gets(A); int DP[1005][1005] = {0}; int n = strlen(A); for (int i =原创 2014-11-15 11:41:38 · 1620 阅读 · 0 评论 -
UVA - 10192 Vacation
#include #include #include using namespace std;int main() { char A[105], B[105]; int t = 0; while (gets(A) && A[0] != '#') { gets(B); int n = strlen(A); int m = strlen(B); int DP[105][原创 2014-11-15 11:38:56 · 1499 阅读 · 0 评论 -
UVA - 10066 The Twin Towers
#include using namespace std;int main() { int n, m, t = 0, A[105], B[105]; while (cin >> n >> m, n) { int DP[105][105] = {0}; for (int i = 1; i <= n; i++) cin >> A[i]; for (int i = 1; i原创 2014-11-15 11:36:37 · 1547 阅读 · 0 评论 -
UVA - 562 Dividing coins
题目大意:给出 n 个硬币的面值, 要求将这 n 个硬币分成两堆(不要求个数平均), 尽量使得两堆硬币的和之差的绝对值最小, 并输出最小值的绝对值解题思路:将 sum 总和看成是背包的容量, 然后进行01背包处理, 然后取尽量接近half的可达到值cur, sum - 2 * cur 就是所要求的值 ans#include int main() { int T,原创 2014-11-21 21:32:28 · 1538 阅读 · 0 评论