======动态规划======
Nicetomeetu-
没有
展开
-
ZOJ - 3735 Cake(凸包,区间dp,最优三角剖分)
对着kuangbin博客开始刷区间dp!按照题目的要求先用Graham扫描法求出凸包,如果凸包上点的数目正好等于输入点的数目,也就说明输入的点恰好构成凸包,否则输出“I can't cut.”。求出凸包后,注意到这是一个环,所以只要把环剪开,就可以用区间dp做了。定义状态dp[i][j]表示i到j这段区间内最优三角剖分的代价,注意此时i和j之间已经有边了。所以状态转移方程为:dp[原创 2017-07-06 18:20:48 · 433 阅读 · 0 评论 -
POJ 1065 Wooden Sticks 最长上升子序列
这道题目和俄罗斯套娃差不多,我们将l 则最后的答案其实就是互相不能相互嵌套的套娃的最大数量那么怎么找这个数目呢?我们可以先按照 l 降序对套娃排序,然后在所有套娃的w中找出最长上升子序列。LIS的长度就是答案。具体的原理也很简单,最长上升子序列中的两个套娃满足 l1 >= l2 && w1 不过要注意一点,排序的时候按照 l 降序排列,如果 l 相等,就按照 w 降序排列参考这原创 2017-03-19 15:20:41 · 380 阅读 · 0 评论 -
POJ 3176 Cow Bowling 动态规划
用dp[i][j]表示从第i行第j列到最后一排所能取到的最大值状态转移方程是:dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + num[i][j];(num[i][j]表示i行j列位置的数字)记忆化搜索超时了,递归形式才63ms,第一次知道了这两者的差异。原来以为只快一点,现在看来。。。。。。代码如下:#include #i原创 2017-02-25 17:29:14 · 270 阅读 · 0 评论 -
POJ 2229 Sumsets 完全背包问题
dp[n]表示n拆分的个数假如n为奇数,dp[n] = dp[n - 1]假如n为偶数1.拆分方案中有1 dp[n - 1]2.拆分方案中没有1 dp[n / 2]所以偶数情况下 dp[n] = dp[n - 1] + dp[n / 2]#include #include #include #include #include #include #include原创 2017-02-26 11:03:14 · 459 阅读 · 0 评论 -
POJ 2385 Apple Catching 动态规划
dp(i, j, k)表示处在时间i, 当前位置是j, 还有k次变换机会所能取到的最多苹果状态转移公式为dp(i, j, k) = max(dp(i + 1, !j, k - 1), dp(i + 1, j, k)) + ((j + 1) == t[i])#include #include #include #include #include #include #i原创 2017-02-26 16:10:19 · 299 阅读 · 0 评论 -
POJ 3616 Milking Time 动态规划
dp[i]表示从第i个区间开始,能挤的最多的牛奶动态转移方程为:dp[i] = max(dp[i + 1], dp[j] + w[i]);w[i]表示第i个区间能挤的牛奶#include #include #include #include #include #include #include #include #include #define MAX_N 1原创 2017-02-26 18:09:12 · 334 阅读 · 0 评论 -
POJ 3280 区间dp
用dp(i, j)表示区间[i, j]变成回文字符串需要的最小代价如果s[i] == s[j]则dp(i, j) = dp(i + 1, j - 1)否则我们就有四种决策消除i, j这两个位置的冲突1.在左边添加一个s[j]字符2.删除s[j]3.在右边添加一个s[i]字符4.删除s[i]我们用add(i)表示添加第i个字符的代价, dele(i)表示删除第i个字符原创 2017-03-14 00:24:06 · 272 阅读 · 0 评论 -
HDU 2191 多重背包问题
状态转移方程为if (j dp(i, j) = dp(i - 1, j);elsedp(i, j) = max(dp(i - 1, j - k * w[i]) + k * v[i]) (j - k * w[i] >= 0)利用滚动数组计算,代码如下:#include #include #include #include #include #include原创 2017-03-15 17:49:05 · 275 阅读 · 0 评论 -
POJ 1742 多重背包问题
假设每个硬币的重量为A[i],数量是C[i] 价格是A[i]定义dp(i, j)为前i件物品装在容量为j的背包中能够取得的最大价值我们只需要求出dp(n, m)因为在求出dp(n, m)的过程中,dp(n, 1) ,dp(n, 2)......dp(n, m - 1)都已经求出来了我们就可以看dp(n, i)是否等于i来判断能否用硬币买价格为i的物品#include #in原创 2017-03-15 20:01:54 · 325 阅读 · 0 评论 -
ECNU CCCC选拔赛 E题 Teacher Panda and plagiarism dp
英语作⽂的 Online Judge 真不是什么靠谱的系统,它有的时候连⽂章是否是抄袭也分不出来。So sad!熊猫⽼师,ECNU 英语教师,对此事表⽰⾮常⽣⽓。在周⼀的英语课上,他⼤发雷霆,谈论抄袭的弊端。他甚⾄对抄袭⾏为进⾏了分类:• 相似度⼤于 20%,认定为抄袭 (COPY);• 相似度⼤于 60%,认定为剽窃 (PLAGIARISM);• 相似度为 100%,认定为「谋杀原创 2017-03-13 20:02:43 · 408 阅读 · 0 评论 -
POJ 1784/EOJ 1447 Huffman's Greed 动态规划
本题给出了关键字k1,k2....kn并且k1假如用e(i,j)表示ki,ki+1,ki+2...这几个关键字构成的最优搜索树的代价。这个状态可以怎么转移呢?现在我们有多种决策,即选择ki...kj中的哪一个作为最优搜索树的根节点。那么再来思考一个问题,当一个二叉搜索树作为一个根节点的子树使,它的代价会怎么变?显然树上每一个节点的深度都会加1,所以代价就会增加pi+...pj + qi原创 2016-10-25 14:30:53 · 934 阅读 · 0 评论 -
HDU - 6170 Two strings dp
欢迎使用Markdown编辑器写博客本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦:Markdown和扩展Markdown简洁的语法代码块高亮图片链接和图片上传LaTex数学公式UML序列图和流程图离线写博客导入导出Markdown文件丰富的快捷键快捷键加粗 Ctrl + B 斜体 Ctrl + I 引用 Ctrl原创 2017-08-23 13:37:42 · 405 阅读 · 2 评论 -
(2017多校训练第四场)HDU - 6078 Wavel Sequence dp
传送门:点击打开链接定义状态dp[i][j][0]表示以a[i],b[j]结尾的且为波谷的情况总和,dp[i][j][1] 为波峰。对于某个i,j满足a[i] == b[j],则dp[i][j][0] = sum(dp[x][y][1]), x a[i]设sum[i-1][y][1] = ∑dp[x][y][1] , x 则dp[i][j][0] = ∑sum[i-1][y]原创 2017-08-11 16:44:06 · 462 阅读 · 0 评论 -
SHU OJ - 415 A序列 最长上升子序列
题目链接:A序列dp1[i]代表以第i个字符结尾的最长上升子序列的长度dp2[i]代表以第i个字符开始的最长下降子序列的长度用nlogn的算法更新这两个dp数组。最后的答案就是max(min(dp1[i], dp2[i]) * 2 - 1) (0 代码如下:#include #include #include #include #include #include原创 2017-07-12 22:19:11 · 437 阅读 · 0 评论 -
Light OJ - 1422 Halloween Costumes (区间dp)
思路很精巧的一道题目,看了大牛的博客猛然惊醒。我的脑回路仿佛天生和有些题目冲突,不管怎么思考都想不到那个重要的点上去。有时候感觉自己这个方向是对的,就是还差了一点点想不出来而已,但是看了题解之后往往会发现真正的解和我所想相差甚远,基本不在一个次元。在多次的实验中,我发现我的每一次思考都在被上一次影响着,换句话说我见到这道题目的第一印象基本决定了我在这道题上能走多远。虽然总是在努力的思考着,但是原创 2017-07-08 10:53:13 · 354 阅读 · 0 评论 -
SPOJ GCJ1C09C (区间dp)
对监狱区间dp,也很好理解,不再赘述。#include #include #include #include #include #include using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 10005;int a[maxn];int P, Q;struct State{ int原创 2016-11-29 22:01:27 · 389 阅读 · 0 评论 -
POJ - 1651 Multiplication Puzzle (区间dp)
题目链接:Multiplication Puzzle定义状态dp[i][j]表示将区间[i, j]全部取完所需要的最小代价,答案就是dp[1][n - 2]。状态转移方程为:dp[i][j] = min(dp[i][k - 1] + dp[k + 1][j] + a[i - 1] * a[k] * a[j + 1]) (i 代码如下:#include #include #inc原创 2017-07-07 14:23:05 · 319 阅读 · 0 评论 -
POJ - 2955 Brackets (区间dp)
题目链接:Brackets定义状态dp[i][j]表示i到j这段区间内最长括号序列的长度。根据题目信息,最长括号长度有两种方式得到。1、如果s[i]和s[j]匹配的话,dp[i][j] = max(dp[i][j], dp[i + 1][j - 1] + 2)2、否则枚举中点k,[i, j]内的最长括号序列是由[i, k]和[k + 1, j]拼接而成,dp[i][j] = max原创 2017-07-06 20:09:13 · 270 阅读 · 0 评论 -
EOJ1765 Nested Dolls 最长上升子序列
本题我试过很多方法,最开始的思路是,一个娃娃可以套另一个娃娃,这种偏序关系可以建图。找出图中最长的路径,然后把那些点删掉,再找出最长的路径,删掉,直至图中没有点,删除的次数就是答案,可是这样会超时。第二个想法差不多,按照w+h的值递增的顺序对娃娃排序,然后用nlogn算法找出lis数组。然后利用lis数组不断的删除最长的子序列。其实和第一种思路差不多,但是还是超时。第三种就是按照w+h递减的顺序排原创 2016-10-22 16:42:53 · 1008 阅读 · 1 评论 -
POJ 3046 Ant Counting dp
定义状态为前i种蚂蚁能够形成大小为j的集合的种数注意到每次都要求一段dp数字的和,我们可以使用一个前缀数组sum。由于sum数组的使用,我们可以在O(1)的时间内算出dp(i, j)同时注意到dp(i, j)只和dp(i - 1, j)有关系,所以我们可以用滚动数组来实现。最后复杂度为O(T * A)#include #include #include #原创 2017-03-19 01:02:41 · 343 阅读 · 0 评论 -
POJ 3181 Dollar Dayz 完全背包 + 高精度
定义状态为前i个金币能组合成总金额为j的方案总数状态转移方程为和完全背包类似,可以化简成因为这道题最后会爆long long int在大神的博客里面学到了一招,将答案拆成两半,用两个dp数组存。一个存高18位,一个存低18位。#include #include #include #include #include #include #define MAX_N原创 2017-03-19 11:54:52 · 437 阅读 · 0 评论 -
HDU 4507 吉哥系列故事——恨7不成妻 数位dp
题目链接:吉哥系列故事——恨7不成妻。此题和HDU 3652 B-number这道题很相似,如果题解看不懂,可以先看3652这道题。代码如下:#include #include #include #include #include #define mod1 (m+7-(j*(bit[i]%7))%7)%7#define mod2 (n+7-j%7)%7using原创 2017-06-04 18:52:05 · 364 阅读 · 0 评论 -
HDU 4734 F(x) 数位dp
定义状态dp[i][j][m]表示以j开头的i位十进制数字中,函数值小于等于m的数字的个数。有如下状态转移方程代码如下:#include #include #include #include #include using namespace std;int A, B, bit[15];int dp[15][15][5005];int digit[15], l原创 2017-06-09 18:20:36 · 389 阅读 · 0 评论 -
HDU 3555 Bomb 数位dp
类似这道题目:HDU 2089 不要62讲解就略过了,和上面那题完全一样。#include #include #include #include #include using namespace std;typedef long long int LL;LL dp[65][10];void init(){ for (int i = 0; i <= 9; i+原创 2017-06-30 18:56:41 · 398 阅读 · 0 评论 -
CodeForces - 55D Beautiful numbers 数位dp+离散化
题目链接:Beautiful numbers很容易想到定义状态为dp[pos][sum][lcm]原创 2017-07-04 13:15:55 · 488 阅读 · 0 评论 -
POJ - 3252 Round Numbers 数位dp
定义状态dp[pos][zero][one],pos为当前数位,zero为前缀中0的个数,one为前缀中1的个数。注意前导0!假如要计算小于等于12的Round Number个数,12的长度为4,在dfs到3的时候,路径上的数字依次为0011,0的个数大于1的个数,所以3是符合条件的。真的对吗?实际上前两个0都是前导0,去掉前导0之后,就发现3其实是不合法的了。所以dfs的时候,维护一原创 2017-07-04 15:04:58 · 590 阅读 · 0 评论 -
HDU - 3709 Balanced Number 数位dp
题目链接:Balanced Number枚举中心轴,然后dfs即可。很容易就想到定义状态为dp[pos][pivot][left][right],pos为当前数位,pivot为中心轴,left为中心轴左边的权值和,right为中心轴右边的权值和。临界条件判断left是否等于right。我们知道左右两边的权值和最大值大约是1500,这样一来空间复杂度就变成了18 * 18 * 1500原创 2017-07-04 23:06:33 · 302 阅读 · 0 评论 -
HDU - 4352 XHXJ's LIS 数位dp+离散化
题目链接:XHXJ's LIS初看这道题目首先回忆起LIS的O(nlogn)的做法,于是想到定义状态dp[pos][LIS*][k],pos代表当前数位,LIS*代表由前缀构造的LIS数组,k代表最长上升子序列的长度。问题来了,一个数组肯定不能作为下标,所以我们要把这个数组转化成数字。注意到数组的每个元素取值范围都是0~9,数组的长度最大为10,所以一个最简单的想法就是把数组转化成一个原创 2017-07-05 17:19:21 · 449 阅读 · 0 评论 -
SPOJ - BALNUM Balanced Numbers 数位dp+状态压缩
1、状态压缩,用一个10位的3进制数字来表示0~9的状态,0表示未出现过,1表示出现奇数次,2表示出现偶数次。2、输出时不要用I64d。#include #include #include #include #include #include #include using namespace std;typedef long long int LL;LL dp[20]原创 2017-07-05 18:48:41 · 405 阅读 · 0 评论 -
异或求和式 数位dp
异或求和式给定长度为n的序列A[i],求所有A[i]xor A[j] (i输入第一行一个整数N接下来N行,第i行为A[i]输出所需的值样例输入3735样例输出12样例解释7 xor 3+3 xor 5+7 xor 5 = 4+6+2 = 12 先把原创 2017-06-03 18:57:45 · 2453 阅读 · 0 评论 -
URAL 1057 Amount of Degrees 数位dp
原题链接:URAL 1057 Amount of Degrees做了前两道数位dp,作者就在想:“数位dp原来这么简单啊,连状态都是一个模式,都是dp[i][j]表示以j开头的i位数字,看来再刷一道题就可以完全学会数位dp了。”可是这道题目现场打脸,orz,一点思路都没有,用前两道类似的状态根本无法解决此题。直到看了大神的论文才知道数位dp的水原来这么深(可能只是本渣觉得深),以后还是老老原创 2017-06-03 17:12:31 · 681 阅读 · 0 评论 -
POJ 1631 Bridging signals 最长上升子序列
直线 L1 如果和 L2 不相交,那么L1的左右端点要么都小于L2,要么L1的左右端点都大于L2。因为题目给的数组已经保证了左端点递增,所以我们只需要求这个数组的最长上升子序列就行了。#include #include #include #include #include #include #define MAX_N 50005using namespace std;t原创 2017-03-19 16:12:39 · 385 阅读 · 0 评论 -
POJ 3666 Making the Grade dp + 离散化
定义状态为前i个数字形成的以数字j结尾的单调序列的最小花费有如下状态转移方程经过化简可得可以用滚动数组实现时间复杂度是O(N*1e9)空间复杂度是O(1e9)两个复杂度都太高了。注意到n远远小于1e9,所以想到离散化。(当然我是想不到)离散化的方法就是将n个数字和1-n对应起来我们dp的时候其实是不用dp出1e9的所有数据的,我们只需要dp出原创 2017-03-20 01:29:37 · 408 阅读 · 0 评论 -
POJ 2392 Space Elevator 多重背包
构造最优解实际上取决于两个参数:1.当前海拔 2.能用的石块的集合同时很容易想到要按照石块的最大海拔降序排列(升序也可以)然后定义状态为前i个砖块,在当前海拔为j的情况下能够堆叠的最大高度然后便得到状态转移方程如下和多重背包化简的方式类似,有两种情况1.如果 h[i] * c[i] >= a[i] 说明在算第i个砖块的情况时, 不管当前海拔是多少,砖块的数量都足以使得海原创 2017-03-26 21:12:50 · 316 阅读 · 0 评论 -
POJ 2184 Cow Exhibition 0-1背包
题目意思:有n头牛,每头牛有两个属性s, f。要求从中选择一些牛,使得它们的 s 值的和 ts 大于零,f 值的和 tf 大于0,并且使得 ts 加上 tf 最大。关键1:要将问题转化成0-1背包一看题目就知道这是一个取和不取 的问题,很容易想到背包。不过怎么转化呢?可以将每头牛的 s 值看成重量,f 值看成价值。定义状态 dp[i][j] 表示前 i 头牛重量和为 j 的时候能够取得最大原创 2017-04-27 23:26:03 · 281 阅读 · 0 评论 -
POJ 2677 (算法导论15-3)双调欧几里得旅行商问题 dp
首先按横坐标递增给所有点排序。定义状态dp[i][j]表示从点i向n走一条路L1,从点j向n走另一条路L2(如下图,两条路互不相交,并且L1在L2上面),L1 + L2的最小值。程序中用distance(i, j)表示点i到点j的距离。如何计算dp[i, j]呢?我们考虑k = max(i, j) + 1这个点,这个点肯定在L1或者L2上。k在L1上时,如下图原创 2017-05-05 16:00:40 · 930 阅读 · 1 评论 -
POJ 3356 AGTC(算法导论15-5编辑距离) 经典dp
POJ 3356 为算法导论原题简化版,这里只讲算法导论版编辑距离。定义状态dp[i][j]表示将x[i……m]变为y[j……n]所需要的最小代价。对于每一个状态,有6种操作,具体如下。1、复制 功能:i + 1,j + 1代价:cost12、替换功能:i + 1,j + 1代价:cost23、删除功能:i + 1,j不变代价:cost34原创 2017-05-05 16:11:44 · 788 阅读 · 0 评论 -
HDU 2089 不要62 初探数位dp
第一次写传说中的数位dp,久仰大名终于得见真容,无比激动!数位dp就是求在给定的区间[l, r]内满足条件C的数字的个数,这类区间统计问题往往可以用数学上的递推来描述,也就是dp了。关于这道题,定义状态dp[i][j]表示以数字j开头的i位数字中不含62和4的个数。什么意思呢?dp[2][6]就表示以数字6开头的两位数字中不包含62和4的个数。也就是61,63,65,66,67,68,69原创 2017-05-27 19:31:53 · 607 阅读 · 0 评论 -
HDU 3652 B-number 数位dp
和HDU 2089 不要62 初探数位dp这道题思路类似,先将dp数组预处理,再利用dp数组的结果计算[0, n)区间符合条件的数字的个数。定义状态dp[i][j][k][l]表示以j开头的i位数字中模13余l的数字个数,k = 0表示这些数字不包含13, k = 0表示包含13。然后按照相同的思路计算[0, n)内满足条件的数字个数,只不过要维护一个状态变量flag,flag =原创 2017-06-03 11:27:06 · 426 阅读 · 0 评论 -
POJ - 2762 && HDU 6165 Tarjan缩点+dp最长路
题目 POJ 2762 HDU 6165 分析 最开始想的是拓扑排序,因为拓扑序列满足如果一个点u可以到v,那么u一定在v的前面。如果求出了拓扑序列,发现序列中u在v的前面,那么就可以认为u可以到达v了。 但是随后想到两个问题如果有环的怎么办呢,就不能求拓扑序列了。虽然这个图存在拓扑序列1-2-3,但是我们能仅仅因为1在2的前面就认为1可以到2吗?显然原创 2017-08-24 11:32:09 · 574 阅读 · 0 评论