DP
big up
这个作者很懒,什么都没留下…
展开
-
uva104 (DP + floyd)
题目大意: 给你两两国家之间的汇率,要求你从任何一个国家出发,身上带着1(单位不明),然后回到这个国家时,身上的钱能够> 1.01.并且如果这样的路径有多条的话,希望的到的是最短的路径,并且还有要求你输出这个最短的路径。思路: 利用DP去求出从i到j中间经过l个国家后所获得的金钱。 那么dp[i][j][1]表示的是从i到j国家之间的汇率, 所以dp[i][j][l] = max(dp[i]原创 2016-03-13 14:54:39 · 353 阅读 · 0 评论 -
关于要求一串数字不超过某个数字可以达到的最大和(DP背包问题)
类似题目: uva562 uva624可以先将所有的值加起来,然后两层for。 外面一层是关于值的循环,里面一层是关于还有多少容量的循环。 for(int i = 1; i <= n ; i++) { for(int j = sum; j >= a[i]; j–) { dp[j] = max(dp[j],dp[j - a[i]]+a原创 2016-05-12 19:41:13 · 649 阅读 · 0 评论 -
uva11552
题目大意: 给出一个数字k和一串字符,k个字母为一个子串,连续的相同的字母组成一个chunks,求字符串中最少的chunks个数。思路: DP。 dp[i][j]表示的第i个子串中第j个字母作为最后一个字母最少可以有多少个chunks. 当第i-1个字串中出现了与第i个字串中相同的字母并且第i个字串只有一个chunks或者第i个子串的最后一个字母跟第i-1个字串的最后一个字母不相等的话,那么原创 2016-04-18 15:14:08 · 578 阅读 · 0 评论 -
uva11404
题目大意: 给出一个字符串,求出最长的回文串,如果有多种答案的话,按字典序最小输出。思路: 刚开始没有看清楚就直接正序逆序求最长公共子序列,结果发现是错的。 后来参考了别人的代码发现,求出最长公共子序列的思路是正确的,但是呢,可能出现特例 例如: kfclbckibbibjccbej jebccjbibbikcblcfkbcibbibc是他们的最长公共子序列,但是这并不是一个回文串,但是原创 2016-04-18 15:51:33 · 786 阅读 · 1 评论 -
uvalive4731
题目大意: 给出数字的个数n以及要分成的组数w。 然后给出各个数字的概率, 求最小的数学期望。思路: DP。因为要求最小的数学期望所以概率大的应该摆在前面,所以要先排序一下。 dp[i][j]表示的是第i组前j个数字可以得到的最小的数学期望。代码:#include <iostream>using namespace std;#include <cstring>#include <st原创 2016-04-18 16:41:58 · 444 阅读 · 0 评论 -
uvalive4727
题目大意: 给出n,k,n表示的是数字的个数,数字都是从1开始的。 k表示的是每隔几个挑选出一个数字。 输出最后的三个数字。思路: 约瑟夫环问题。 类似于uvalive3882代码:#include <iostream>using namespace std;#include <cstring>#include <stdio.h>int dp[500005];int main()原创 2016-04-19 20:05:44 · 379 阅读 · 0 评论 -
uva11795
题目大意: 给出有几个怪兽以及初始的可以打的怪兽的二进制序列。为1的就是可以打的为0的就是不可以打的。 打死一只怪兽后你就可以用它的武器去打特定的怪兽。 问最多有几种方案。思路: 状态压缩DP。 S[i]表示的是当死的怪兽的状态为i的时候所获得的武器可以打死哪些怪兽。 weapon[i]表示当打死怪兽i的时候所可以获得的武器。 dp[i]表示当死的怪兽的状态为i的时候最多可以有几种方案原创 2016-04-19 20:10:33 · 636 阅读 · 0 评论 -
uva10564
题目大意: 给一个如题目上给的图。要求从第一层走到最下面一层,只能往左下或右下走,经过的数字之和为sum。 问有多少条路径之和刚好等于S? 如果有的话,输出字典序最小的路径。思路: dp[i][j][k]表示从坐标(i,j)走到最后一层的和要为k的方案数。 由于它只能往左下或者右下走,所以dp[i][j][k] = dp[i + 1][j][k - val] + dp[i + 1][j +原创 2016-04-19 20:59:12 · 292 阅读 · 0 评论 -
uva10069(DP + 高精度运算)
题目大意: 给出A,B两个串,问A串中有多少个B串思路: 因为A串可以达到非常大,所以需要用到大数相加。 dp[i][j]表示B中前i个字符在j中的前j个字符中有几个 当i和j是一样的情况下,dp[i][j]等于B的前i个字符在A的前j-1个字符中的个数加上B的前i - 1个字符在A的前j - 1个字符中的个数 dp[i][j] = dp[i][j - 1] + dp[i - 1][ j原创 2016-05-15 12:09:11 · 306 阅读 · 0 评论 -
uva624(DP)
求解: for(int i = 0; i < tracks; i++) { for(int j = N; j >= 0;j–) { if(j >= t[i] && dp[j] <= dp[j - t[i]] + t[i] && dp[j - t[i]]+t[i] <= N) { dp[j] = d原创 2016-05-12 19:35:35 · 431 阅读 · 0 评论 -
uvalive4256
题目大意: 给出一个无向联通图和一串数字,然后要你修改这串数字,使得数字在无向联通图中是连通的或者它们是相等的。思路: DP。 dp[i][j]表示的是从1到第i个数字以j结尾需要修改多少个数字。 dp[i][j] = min(dp[i][j],dp[i - 1][k] + (j == x?0:1)) 其中x表示的是给出的序列中第i个位置的数字是多少。 这个状态转移方程的前提是j跟k必须是原创 2016-04-16 17:02:37 · 337 阅读 · 0 评论 -
uva11584
题目大意: 给出一个字符串,问最少可以分成几个回文串思路: 直接枚举出左边界和右边界然后判断两个边界之间是否可以有回文串,然后DP选择出一个较小的。详细见代码。 代码:#include <iostream>using namespace std;#include <cstring>#include <stdio.h>char s[1010];int f[1010];bool check原创 2016-04-16 16:26:37 · 737 阅读 · 0 评论 -
uva590
题目大意: 给定两个数n,k,n个城市,k次航班,然后给出n*(n-1)条航班记录,前(n-1)行代表第一个城市分别到其他城市的航班,如果消费为0,则代表没有航班,例如第一个样例,前两行表第一个城市到第二个城市和打三个城市的所有航班,接下来的(n-1)行,代表第二个城市到第一个城市和第三个城市的,现在要求出从第一个城市出发,经过k次航班,到达第n个城市所需要的最小花费是多少?思路: 状态转移方程原创 2016-02-28 19:57:34 · 287 阅读 · 0 评论 -
uva10739
题目大意: 通过增加字符,删除字符,替换字符将给出的字符串以最小的代价变成回文。思路: 状态转移方程: dp[i][j]表示i到j变成回文的最小步骤。 如果s[i] == s[j]的话,那么dp[i][j] = dp[i + 1][j - 1] 如果s[i] != s[j] 的话,那么dp[i][j] = min(dp[i + 1][j],dp[i][j - 1],dp[i + 1][j原创 2016-02-28 20:34:31 · 295 阅读 · 0 评论 -
uva10304 区间DP
题目大意: 求二叉搜索树的最小的代价。 代价 = 节点的值 * 到根节点的边数思路: dp[i][j]表示从i到j需要付出的最小的代价 分成两个区间 分界点为根节点,根节点左边是左子树,右边是右子树 k不用算进去 因为是根节点不用付出任何代价 左子树付出的代价 + 右子树付出的代价 由于根节点使得左右子树的深度增加了1 dp[i][j] = min(dp[i][k - 1] + dp原创 2016-02-28 21:13:16 · 203 阅读 · 0 评论 -
uvalive4490(状态压缩 + dp)
题目大意: 从左到右给出n本数的高度和最多可以抽取的书本的数量k,如果书本与相邻的书本的高度不相同的话就是一个段,段越多混乱度就越高。求最低的混乱度。思路: dp[i][j][s][end]表示前i本书操作了j次,剩下的书的状态为s,最后一本书是end的最低的混乱度。 那么对于一本书有两种情况: 1. 跟其前面的书籍的高度是一样的 那么dp[i][j][s][end] = min(dp[i原创 2016-04-26 22:21:23 · 499 阅读 · 0 评论 -
uvalive4987
题目大意: 有n支施工队在修一条笔直的高速公路,其中第i支队伍离告诉公路起点的距离是ai,另外还有m个避难所,其中第i个避难所离高速公路的起点的距离是bi,给每只施工队分配一个避难所,距离是|ai,-bi|,求使得所有施工队移动距离的总距离最小,每个避难所最起码有一个施工队,打印每个施工队伍的避难所号思路: dp[i][j]表示前i只队伍到前j个避难所(前j个避难所每个都有施工队)所需要移动的最原创 2016-04-27 11:38:14 · 393 阅读 · 0 评论 -
uvalive4625(dp + 二分)
题目大意: 给你一串 n 个数,表示n个球,给你这n个球的重量,要你把这n个数分成 m - 1 段,每段的数字个数都是偶数,对于每一段,它的半段数字个数都不超过d,找出一种分发,使所有的这些半段的重量的最小值,并输出这个最小值。思路: 详细见代码解释 代码:#include <iostream>using namespace std;#include <cstring>#include原创 2016-04-27 15:07:49 · 539 阅读 · 1 评论 -
uvalive4613
题目大意: 给出n辆车的行走方向,到达时间和通过某段路的时间。 有一个单行道,只能让一辆车经过,为了保证安全两辆车之间经过同一个点的时间差要>=10 问所有的车经过这段路的最少时间。思路: dp[i][j][k]代表的是方向向左的经过i辆方向向右的经过j辆最后一辆车的方向为k的时候的经过这段路所需要使用的最少时间。 那么假设前一辆车发车的时间为s,到达终点的时间为t那么当前的车的发车是时间就原创 2016-04-27 15:43:16 · 378 阅读 · 0 评论 -
uvalive3608(二分 + DP)
题目大意: 给出a,b两个串,a串可以分成若干串,问将a的每个分开的串分别转化为b串,最少的操作数是多少思路: 二分答案,避免超时。 dp[i][j]表示在a串的第i个字符和j串的第j个字符最少的操作数是多少。 那么当a的i + 1个字符和b的j + 1个字符相等时候,它的最小操作数是和a到i个字符和b到j个字符的值是一样的。 那么当a到i个字符和b到j + 1个字符的时候,此时最小的操作原创 2016-05-10 23:15:29 · 3054 阅读 · 0 评论 -
关于求最长递增子序列会超时的问题(使用栈)
类似于uva10524的题目。 uva10534的题目大意是给出一串数字,最多有10000个,问这串数字里面可以组成的前n个数字递增和后n个数字递减的最长序列是多少。如果直接用求最长递增子序列的方法的话,有两层for肯定是会超时的。那么可以使用堆栈的方式,用栈保存数字。 如果遇到第一个数字或者遇到比当前的栈顶数字更大的数字的话那么就将其存入栈顶中。 如果遇到的数字不比栈顶大的话,那么就找栈中刚原创 2016-05-15 14:43:59 · 515 阅读 · 0 评论 -
uvalive2038(树形DP基础题)
题目大意: 给定一棵树,要求选择尽量少的点,使得没有被选择的点都可以至少和一个已经选择的点相邻。思路: 树形DP。 类似于01背包问题。 树上的结点要么选要么不选。 dp[i][0]表示第i个结点不选 那么dp[i][0] += dp[j][1] 其中j是i的子树的根节点。 dp[i][1]表示第i个结点要选 那么dp[i][1] += min(dp[j][1],dp[j][0])发原创 2016-04-20 17:35:18 · 365 阅读 · 0 评论 -
关于硬币组合问题和DP的结合
例题: uva674 uva117 uva562 uva11137题目的大概意思就是给定某些面值的硬币,有无限多个,问有几种组成方法等等。有点类似于完全背包。思路: 利用两层for,第一层枚举出各种不同面值的硬币,第二层枚举题目可能达到的钱的面值。 dp[j + coin[i]] += dp[j]; 表示j + coin[i]组成的方法等于原来的加上可以组成j的方法。代码:#inclu原创 2016-05-18 14:50:19 · 704 阅读 · 0 评论 -
DP与回文串
可以对字符串进行增删改变成回文串,每增删改一次算一步,问变成回文串的最少步数。 uva10739 代码:#include <iostream>using namespace std;#include <stdio.h>#include <cstring>char str[1005];int dp[1005][1005];int main() { int T; int k原创 2016-05-15 21:44:56 · 652 阅读 · 0 评论 -
uva10029(hash + DP)
题目大意: 按照字典序给出一系列的字符串,如果上面的字符串可以通过增删改一个字符得到下面的字符串的话,问这一系列的字符串可以最多有几个这样的字符串使得上一个可以通过增删改得到下一个字符串。思路: 最先想到的是暴力。。但是看到字符串最多可以有25000个,双层for肯定直接TLE。看到人家用了增删改。首先将给定的字符串都给定一个hash值,然后将每个字符串在每个位置用增删改,这样不会超时因为最多就原创 2016-05-18 15:07:31 · 301 阅读 · 0 评论 -
uva10313(二维多重DP)
题目大意: 给出N,l1,l2,N表示钱的面值,问将N拆分可以有多少种拆分数。 有三种情况: 1,给出N,将N拆分成面值不超过N的硬币可以有多少种不同的拆分数。 2,给出N和l1,将N拆分成面值不超过l1的硬币可以有多少种不同的拆分数。 3,给出N和l1和l2,将N拆分成面值在l1到l2范围内的硬币可以有多少种不同的拆分数。思路: dp[i][j]表示将面值为i拆分成面值不超过j的硬币可原创 2016-05-18 15:55:55 · 429 阅读 · 1 评论 -
uva10401
题目大意: 给出一个字符串,?表示皇后可以放在这一列的任何位置,如果是数字或者字母表示可以只能放在相应的行。问最多可以有多少种放法。思路: dp[i][j]表示皇后放在(i,j)最多可以有多少种放法。从第一列往后面去递推。 k表示除了与皇后相近的那三行外,dp[i][j] += dp[k][j - 1]。结合了前j - 1列。代码:#include <iostream>using names原创 2016-05-18 17:20:28 · 256 阅读 · 0 评论 -
uva10891
题目大意: 博弈,求A-B的得分的最大值。思路: 区间DP; 让B尽量小。 sum = A + B ;A - B = A-(sum - A) = 2 * A - sum A = sum - min(B);代码:#include <iostream>using namespace std;#include <cstring>#include <stdio.h>const int ma原创 2016-01-28 17:07:44 · 604 阅读 · 0 评论 -
uva662(DP)
题目大意: 给出n和k,分别表示在n个餐馆需要建立k个仓库,需要求出最小代价,代价就是n个餐馆到离它最近的仓库的距离的和。思路: dp[i][j]表示在前j个餐馆建立了i个仓库。 cost[i][j]表示从i到j建立一个仓库,需要花费的最小的代价。(那么肯定是建在中位数的位置) 那么dp[i][j] = min(dp[i][j],dp[i - 1][k] + cost[k + 1][j]);原创 2016-05-19 16:38:15 · 388 阅读 · 0 评论 -
uva10626(记忆化搜索)
题目大意: 一瓶可乐需要花8元,自动贩售机只收1元,5元,10元。每次插入的钱只能买一瓶。 给出n瓶可乐,请问最少插入几次钱可以买到所需要数量的可乐。思路: 一共有以下几种情况: 8个1元 插入8次 3个1元 一个5元 插入4次 3个1元 一个10元 插入4次 找5元 1个10元 插入1次 找2*1元 2个原创 2016-03-03 12:52:19 · 352 阅读 · 0 评论 -
uvalive3637(DP)
题目大意: 给出n本书,又分别给出书本的高度和宽度,要建立一个三层的书架,书架的高度为三层书架的高度和,书架的宽度是三层中最宽的那层书架的宽度,问最小的书架的面积是多少思路:(有三层只需要考虑两层,第三层自动确定了) DP。按照书本的高度从大到小进行排序。 较难想到的DP。 设dp[i][j]表示的是第2层宽度为i第3层宽度为j时候的最小高度。由于顺序已经是从大到小排序的了。所以放入书架的第原创 2016-05-07 15:49:10 · 660 阅读 · 1 评论 -
uvalive3305(双调欧几里德旅行问题)
题目大意: 给出坐标是按照x从左到右排序好的,求从最左走到最右再从最右走到最左边的最短路程思路: 双线性DP。 将一个人从最左端走到最右端,然后从最右端走到最左端等价成两个人同时从最左端不重复的走过中间的点并且到最右端。我们不妨设这两个人为A和B,且总是假定走在前面的人是A。 再设函数dp(i, j)表示A走到i的位置,B走到j的位置,并且所有i,j之前的位置都被不重复的走过的最短距离之和。原创 2016-05-07 15:10:02 · 681 阅读 · 0 评论 -
uvalive4614 (这题不懂)
题意:给你一棵树,有一些点你需要去一定的次数,每去一次你都要回来,求最小的权值和参考的代码:#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define INF 1000000000000000LL using namespace std; const int MAX原创 2016-05-07 14:10:02 · 751 阅读 · 0 评论 -
简单立体几何和DP的结合
将一个面映射到六个面去。 就例如题目给出的这个面是正面,那么你可以使它变成背面,上面,下面等。 然后进行合理性的判断。类似于uva10051代码:#include <iostream>using namespace std;#include <stdio.h>#include <cstring>char wei[6][10] = {"front","back","left","right原创 2016-05-15 19:04:33 · 362 阅读 · 0 评论 -
DP与位运算的结合
uva10651 代码:#include <iostream>using namespace std;#include <cstring>#include <stdio.h>char str[15];int a;int vis[4100];int _min;bool check(int i,int j) { if((j & (1 << (i - 1))) && (j & (1原创 2016-05-15 20:09:23 · 343 阅读 · 0 评论 -
uva10304(二维完全背包DP)
题目大意: 给出一个n和s,然后给出n组x和y,每组都有无数个,求出最少的x和y使得 x^x + y^y == s^s其中x是选出的所有x的和,y是选出的所有y的和思路: 完全背包。 代码:#include <iostream>using namespace std;#include <cstring>#include <stdio.h>const int INF = 0x3f3f3f3原创 2016-05-15 20:31:41 · 302 阅读 · 0 评论 -
uva10271
题目大意: 有一个人需要用三根筷子,其中两根短的长度距离越近越好,长的只要比他们两个都长就可以了,badness = 两根短的长度相减的平方 这个人想在生日会上教朋友们这种方法,有k个朋友n根筷子。 还有包括他在内的八个亲人。 需要3 * (k + 8)根筷子,问最小的badness是多少。 思路: 将筷子从大到小输入。 dp[i][j]表示的是前i根筷子前j个人最少的badness是原创 2016-05-15 21:51:32 · 582 阅读 · 0 评论 -
uvalive3363
题目大意: 压缩字符串。 例如 letsgogogo = lets3(go) letsgogogo的长度是10 lets3(go)的长度是9 3(go)的长度计算:每个字符算1的长度 所以这是5思路: 字符号DP。 区间DP。 dp[i][j]表示在从i到j可以达到的最短的产地故代码:#include <iostream>using namespace std;#include原创 2016-04-20 17:57:09 · 260 阅读 · 0 评论 -
uva10564
题目大意: 给一个如题目上给的图。要求从第一层走到最下面一层,只能往左下或右下走,经过的数字之和为sum。 问有多少条路径之和刚好等于S? 如果有的话,输出字典序最小的路径。思路: dp[i][j][k]表示从坐标(i,j)走到最后一层的和要为k的方案数。 由于它只能往左下或者右下走,所以dp[i][j][k] = dp[i + 1][j][k - val] + dp[i + 1][j +原创 2016-04-21 18:41:30 · 471 阅读 · 0 评论 -
uvalive4394(区间dp)
题目大意: 给出两个字符串;每次可以选择第一个字符串的一个区间,全部刷成某一个字母; 问最少刷几次可以刷成第二个串;思路: dp[i][j]是区间(i,j)最少需要刷多少此。 如果a[i] == a[k] 那么dp[i][j] = min(dp[i][j],dp[i + 1][k] + dp[k + 1][j]) 因为i 和k相等的话,那么k就不需要在刷了,所以分成这两个区间算的话会是最原创 2016-04-21 18:46:42 · 432 阅读 · 0 评论