
动态规划
只玩三国的程序猿
23333333333
展开
-
LightOJ 1013 - Love Calculator
题意:题意就是给你两个字符串,求能同事包含这两个字符串的最短串的长度和种数。一个结论:最长包含串的长度=len(s)+len(t)-len(lcs(s,t)).另外统计的方法和求lcs的方程转移差不多。//// Created by CQU_CST_WuErli// Copyright (c) 2015 CQU_CST_WuErli. All rights reserved.///原创 2015-11-20 21:32:45 · 487 阅读 · 0 评论 -
UVA 11324 The Largest Clique(SCC+dp)
题意: 让你在一个有向图中找到一个点的集合,是的这个点的集合中任意一堆点之间都有路劲相连。 一开始好像,就是先缩点,但是缩点之后生成的那个树,如何来找到一个最大的点集呢?考虑到这是一棵树,每个点都面临着选或不选的决策, 所以我们可以考虑利用树形dp来解决这个问题。代码://// Created by CQU_CST_WuErli// Copyright (c) 2016原创 2016-03-05 00:14:14 · 459 阅读 · 0 评论 -
POJ 3494 Largest Submatrix of All 1’s(单调栈||dp)
题意:给你一个0-1矩阵,让你在里面找一个最大的全是1的子矩阵。具体思路是这样的: 我们首先先统计出a[i][j]之前的连续的1的个数sum[i][j], 然后分别向上和向下延伸,找到第一个上界up和下届down使得 sum[i][j]是sum[up][j]到sum[down][j]之间的最小值, 也就是找到sum[i][j]作为最小值的最大区间,那么以当前 位置为原创 2016-02-23 22:59:55 · 725 阅读 · 0 评论 -
HDU 4085 Peach Blossom Spring(斯坦纳树+dp)
题意: 给你一些点和边,让你选择一下边,是的前k个点和后k个点连通且代价最小,但是除了这2k个点,好友一些其他的点。 一开始我以为是MST,后来发现 不行,然后就是网络流乱搞,然并卵,就是因为有其他的点可用可不用。 后来一看才知道原来是斯坦纳树。。。。如此高级的东西。 斯坦纳树的定义:斯坦纳树问题是组合优化问题,与最小生成树相似,是最短网络的一种。 最小生成树是在给定的点原创 2016-03-08 23:06:08 · 1085 阅读 · 0 评论 -
HDU 1171 Big Event in HDU(多重背包)
题意:给你一些物品,让你分成两堆,使得两队物品的总价值最接近,且第一堆大于等于第二堆。一看就是多重背包,我们只需要把总价值的一半作为背包容量就行了。需要二进制优化,不然可能T,不过貌似数据比较水,不优化也可以过。代码://// Created by CQU_CST_WuErli// Copyright (c) 2016 CQU_CST_WuErli. All rights reser原创 2016-02-25 23:00:17 · 405 阅读 · 0 评论 -
HDU 1300 Pearls(dp)
题意: 给你一些物品的需求量和单价,你可按照给出的清单吗,也可以将某些珍珠用级别更高的的珍珠来替代,但不能用级别低的替代,让你找到一个购买方案,使得的总价最小。 我已开始想的状态时dp[i][j]dp[i][j]表示把第j个里面的一些放在i里面获得的最小值,但是这样的状态太麻烦了,而且是我想多了,因为可以推想要不不拿,要不就整个拿到后面去, 这样就可以保证解的最优性。这样的状态就好办原创 2016-02-27 23:14:36 · 393 阅读 · 0 评论 -
ZOJ 3469 Food Delivery(区间DP)
题意: 多个客人同时向餐厅点餐,客人每多等一分钟,就会增加不愉快度,求一种方案使得客人的总不愉快度最小。 一道典型的区间dp的题目,然而略有不同,dp[i][j][0/1]dp[i][j][0/1]表示解决i到j区间停在i或j所获得的最小值,然后分别向两边递推。递推的起点在餐厅的位置,所以我们要把餐厅的位置加入一起考虑。 转移的方程看代码吧,这里就不写了。代码://// Cre原创 2016-02-27 23:20:05 · 514 阅读 · 0 评论 -
Codeforces 689 C The Values You Can Make(dp)
题意: 给你一些硬币,让你选出一个子集的总价值和为k,然后对于一个选出的子集,除了可以组成k以外,还可以在选出的子集中选出一些其他的价值。问你所有的选出的子集一共可以得到多少种价值。 对于这个,因为tag是动态规划,所以就往上面思考,但是找不到一个一个可行的状态。看过题解才明白,一个很机智的状态。 dp[i][j][k]dp[i][j][k]表示前ii个硬币组成了价值为jj的一个子集原创 2016-07-08 16:11:41 · 927 阅读 · 0 评论 -
Codeforces 685E Travelling Through the Snow Queen's Kingdom(DP)
题意: 给你一张图,每一条边都有一个编号i,经过每条边的时间为1,如果当你到达这条边的时间小于i的话,就必须等到i才能走出这条边,如果大于i,就走不出去了,也就是不通了。然后给你一些询问l, r, s, t,问你是否可以从s出发,时间为l,在r时间之前到达s。解法: 我们假设动态规划的状态为dp[s][t]表示从s到t要花费的最少时间,我们考虑倒叙添加边,这样的话每当新添加一条边(u,v)原创 2017-02-02 21:37:19 · 704 阅读 · 0 评论 -
Codeforces 696B Puzzles(期望+树形dp)
题意: 对树做dfs的时候,每一个点都有一个时间戳,问你如果每次选择子节点都是等概率的情况下,每个点的期望时间戳是多少。解法: 一看就是典型的树形dp求期望的题目,我们考虑的是其他的点对某一个点的贡献度,最后的出的转移方程就是dp[v] = dp[u] + 1 + (sz[u] - sz[v] - 1]) * 0.5。 得到这个方程有两个方法,第一种很好理解,首先子节点最起码比父节点原创 2017-02-02 21:40:29 · 523 阅读 · 0 评论 -
Codeforces 698A Vacations(线性DP)
题意: 每一天都有各种活动,也可以选择休息,问你如何安排才能够在前后两天惊醒的活动不一样的情况下,是的休息的天数最少。分析: 直接暴力进行dp就可以了,注意前后活动不一样是的转移状态的不同。// Created by CQU_CST_WuErli// Copyright (c) 2016 CQU_CST_WuErli. All rights reserved.////#pra原创 2017-02-02 21:41:57 · 515 阅读 · 0 评论 -
HDU 5313 Bipartite Graph(bitset + DP)
题意: 给你一个二分图,问你最多可以添加多少条边,让这个图变成完全二分图。分析: 可以知道的是,完全二分图的边数就是两边的点数相乘,为了让这个值能够最大,我们要让两边的点数尽量相等,所以先预先处理处每一个小二分图的两边的个数,然后dp一下就好了,但是n^2的dp肯定是过不了的,所以我们用bitset来优化一下就好了。bitset的每一位存的是前i个二分图,最多可以让两边的点往n/2靠近的值原创 2017-02-02 21:46:34 · 479 阅读 · 0 评论 -
CodeForces 543A Writing Code(dp)
题意:告诉你每个程序员写一行代码会产生多少bug,问你n个程序员写m行代码bug数不超过b的分派方案有多少个。一开始想到的状态就是dp[i][j][k]表示前i个程序员写了j行代码,bug不超过k的方案,发现转移是三方的,其实这个状态时刻一改变一下的,因为最后的程序员可以写,也可以不写,不管写了几行,所以状态转移就只需要看最后的那个程序员是否写了就行,另外可以滚动数组。dp[i][j][原创 2016-02-02 22:26:37 · 476 阅读 · 0 评论 -
CodeForces 2B The least round way(dp+数学)
题意:给你一个矩阵,让你在里面找一条路径,使得这条路径上的数相乘之后的末尾0最少。一看像是一个dp的题,但是还是需要一点数学在里面(数学渣伤不起),末尾0最少,意味着路径上的数的2和5因子要尽量少,所以我们需要找两条路,一条是2最少的,一条是5最少的,那么答案就是min(a,b),为什么呢?我们设想一下,2最少的那条路保证了其他路上的的2都比这个多,5也是同理,又因为这两条路一般不会是一原创 2016-02-13 19:43:59 · 528 阅读 · 0 评论 -
LightOJ 1005-Rooks
题意:给你一些皇后,问总共有多少种方法是的皇后之间互不攻击。这题和八皇后有点类似,但是我们不能去爆搜,那样肯定会T。于是就要考虑动态规划。dp[i][j]表示i*i的棋盘中放j个棋子的方法数。首先,如果i<j,那么答案就是0。我们先考虑i*i的情况下,我们在他的右下角填一个角,那么肯定可以让这个正方形扩大一圈。在扩大的一圈之中。如果不放,dp[i+1][j]+=dp[i][j];如果只放一个,原创 2015-11-20 21:17:40 · 472 阅读 · 0 评论 -
LightOJ 1017 - Brush (III)
题意:意思就是给你一个刷子宽度是w,每次以一个点为底部,可以把这个点和这个点上面不超过w的点一起刷掉,问最多刷k次,最多能刷几个点。其实这个题和点的x坐标没啥关系,只和y有关系,问题就转化为,给定一个不降序列,去k个互不覆盖的区间,是的区间内最大值和最小值相差不超过w,是的k个区间内的元素个数最多。我们只要与处理出每一个点往上能刷的点数就行。具体看代码。//// Created by C原创 2015-11-20 21:40:31 · 477 阅读 · 0 评论 -
LightOJ 1027-A Dangerous Maze
题意:给你n个门,每个门有一个值,如果是正的,那么就代表在x时间后会出去,如果是负的,那么就会回到开始之后的x秒之后。问,最后出去时间的期望。我们可以假设选正数的概率为p1,之后平均花t1的时间出去;选负数的概率是p2,之后平均花t2的时间出去。设期望为T,T=p1*t1+p2*(t2+T);那么T=正数个数的倒数乘以sigma(abs(x[i])).代码://// Created by原创 2015-11-20 22:07:18 · 579 阅读 · 0 评论 -
LightOJ 1004 - Monkey Banana Problem
题意:简单的数塔,注意分成两部分,转移时两部分有不同。AC代码://// Created by CQU_CST_WuErli// Copyright (c) 2015 CQU_CST_WuErli. All rights reserved.//// #include<bits/stdc++.h>#include <iostream>#include <cstring>#inclu原创 2015-11-20 20:48:54 · 587 阅读 · 0 评论 -
LightOJ 1030-Discovering Gold
题意:题意就是说给你一个长度为n的序列,初始在1位置,每次可以掷骰子,1-6,如果没有越界,就可以往前走,并且得到目标格子的值。走到最后一个格子结束。问最后获得分数的期望。一般来说期望都是倒着推。设dp[i]表示从i号格子出去的期望,那么dp[i]+=dp[i+step]*1.0/(6,n-i).代码://// Created by CQU_CST_WuErli// Copyright原创 2015-11-20 23:04:47 · 551 阅读 · 0 评论 -
LightOJ 1031-Easy Game
题意:给你一个数列,每次可以从左边或者右边去一串连续的数字,并且获得所有数字和的分数,两个人轮流取,A先手,B后手,问最后A最多能比B多多少分。很明显的区间dp,但是又有一些博弈在里面。dp[i][j]表示从i到j,能多拿的分数。转移方程是这样的: for (int i=l;i<=r;i++) ans=max(ans,sum[i]-sum[l-1]-dp[i=1][r]); f原创 2015-11-20 23:15:38 · 628 阅读 · 0 评论 -
LightOJ 1025 - The Specials Menu
题意:其实题意就是问你任意删除字符,能够得到多少个回文字符串。区间dp是没跑的。dp[i][j]代表从i到j里有多少回文串。如果s[i]!=s[j],那么只要只需要统计i到j-1和i+1到j之间各有多少个,再减去i+1到j-1之间的,因为这个重复了(想一想为啥)。如果s[i]==s[j],那么除了统计i+1到j和i到j-1之外,并不需要减去i+1到j-1之间的,因为哪个可以和旁边两个组成新的回文原创 2015-11-20 21:24:58 · 575 阅读 · 0 评论 -
LightOJ 1018 - Brush (IV)
题意:题意就是给一些点,问最少要连几条线,可以将这些点全部覆盖。典型的状压dp用line[i][j]表示在直线i,j上的点。这样,dp[s]表示当前状态为s时,最少需要的次数。具体的剪枝是这样的。因为i和j是肯定要覆盖的,所以,每次能够找到一个可以覆盖的点,覆盖了就可以继续往下,然后跳出。具体看代码。//// Created by CQU_CST_WuErli// Copyright原创 2015-11-20 21:54:50 · 583 阅读 · 0 评论 -
UVa 11688 Rotate to root
题意:模拟二叉树的旋转,不理解先去看看旋转再来看着道题。题目就是问每一个节点旋转到根节点时,树的最大深度。用dp来做。首先,我们来看这个图。图中,hr表示节点x向右旋转过根节点再向右一直到达底部所能达到的最大深度,hl同理。dR,dL分别表示某个节点的左右子节点所能达到的最底部的深度,dr和dl表示该点需要左旋(右旋)多少次才能到达根节点。那么方程就是dp[u]=1+max(max(hl,hr),原创 2015-11-28 22:54:34 · 460 阅读 · 0 评论 -
UVa 11775 Unique Story
题意:题意就是给你两个序列,问你最多可以有多少个互不相同的子序列。可以反过来想,求相同的有多少个,所有的子序列一共有2的n次方个(排列组合公式求和)。一看就是DP,转移方程:dp[i][j]=(sum[i-1][j-1]+dp[i][j]+1)%MOD;dp[i][j]表示以i和j结尾的相同的字符串有多少个,sum[i][j]表示以前i个和前j个能够组成的相同的子序列有多少个。对于这个方程的原创 2015-11-28 23:01:56 · 389 阅读 · 0 评论 -
Codeforces 332B Maximum Absurdity(暴力)
题意:给你一个序列,让你在里面选择两个不想交的长度为k的字段,是的和最大。我第一次做还是用的dp,感觉复杂度有点高啊,后来发现直接预处理就好了。预处理需要三个数组,分别是sum[i],Max[i],Max_id[i]。sum[i]表示以i开头的长度为k的子段和Max[i]表示在i之后的和最大的长度为k的字段和Max_id[i]和上面对应,就是那个最大子段和的其实位置。这样处理好之后=,直原创 2016-02-11 23:13:27 · 618 阅读 · 0 评论 -
HDU 5036 Explosion (bitset + DP)
题意: 给你一张图,每个图都可以到达另一个节点,当然你也可以选择炸开者结点来进入这个图,问你炸开节点的期望次数是多少。分析: 因为每个点是独立的,我们考虑每一个点的单独的期望,到这个点要炸的次数其实就是到这个点的节点数的倒数,所以我们需要把可以到达每个点的点数处理出来,直接求的话,用floyd来求闭包,复杂度不够,所以用bitset来优化。代码://// Created by CQ原创 2017-02-02 21:46:02 · 671 阅读 · 0 评论