ACM_动态规划
文章平均质量分 65
亚N程
这个作者很懒,什么都没留下…
展开
-
HDU:3652 B-number(数位DP)
数位dp。问你能被13整除而且包含13的数字有多少个。这里需要设计状态了。dp【i】【j】【k】【l】表示长i位,以j开头,是否包含13(k=1为包含,0不包含),模13余数为l的数字有多少个。统计的时候和前面略有不同,要计算前面的余数,保证前后的余数之和能被13整除才能统计在内。原创 2014-02-10 10:09:25 · 534 阅读 · 0 评论 -
SDUT:2408 Pick apples(贪心+完全背包)
题意:给一个大小为v的包,有三种苹果,分别给其价值和体积,问最多可装多少价值。思路:v高达10^8,直接完全背包是不行的。由于一共三种苹果,可以考虑优化。在苹果体积是三种苹果体积的乘积时,取可以得最大价值的那种苹果。这样优化以后v大小变成10^6,这样就用完全背包就行了。#include #include #include #include #include #include原创 2015-04-18 17:07:53 · 652 阅读 · 0 评论 -
UVa:10911 Forming Quiz Teams(状态压缩)
集合上的动态规划。就这个题目而言,用整数表示的集合可以很好的表现除去某个元素的集合这种特点。集合中的元素已经隐含了阶段,集合是从较小的子集逐渐枚举到较大的子集的,正符合动规的特点。另外注意用整数表示集合,数组要开到比1原创 2014-03-18 12:32:47 · 578 阅读 · 0 评论 -
ZOJ:3802 Easy 2048 Again (状态压缩)
题意:1维的2048。思路:很好的一道DP。可以观察如4、16、8这样的组合,其中的4就永远都不会被合并,因为以后的结果只能是越来越大。所以可以被合并的数列特征是递减序的,如32、16、4。这样我们可以以当前组合中的末尾递减序列为状态进行DP。这里的状态大小不是非常明显,仔细想想极限情况,有500个16,每2个16形成32,每2个32形成64…如此合并,至多就是16*500的状态,因此开8原创 2015-04-22 12:00:48 · 611 阅读 · 0 评论 -
HDU:4249 A Famous Equation(数位DP)
题意:给一个表达式形如a+b=c,其中一些数字为?,问使表达式成立有多少种情况。思路:不太容易发现是一道数位DP。比较容易建立状态转移方程,dp[i][j][k][l]表示j(0表示不进位,1表示进位)使a的第i位为k,b的第i位为l的情况个数,这样可以计算得c的第i位。用线性时间枚举位数,10^2枚举过去状态,10^2枚举现在状态建立转移即可。最后累加求和。注意前导零的问题。给一组数据??+原创 2015-04-18 14:14:55 · 627 阅读 · 0 评论 -
UVa:10304 Optimal Binary Search Tree(动态规划)
经典的OBST问题。我用了O(n^3)的解法,dp【i】【j】=min{dp【i】【k-1】+dp【k+1】【j】+sum【i】-sum【j-1】+val【k】}其中i一开始想了一个O(n^4)的算法,用dp【i】【j】【d】表示区间【i,j】段数字深度为d时候的最小值,这样多加了一维把问题给复杂化了。实际上这个题可以用四边形不等式优化成O(n^2),以后贴上代码。O(n^3):原创 2014-03-20 08:04:02 · 820 阅读 · 0 评论 -
UVa:10157 Expressions(动态规划+大数)
这个题和http://blog.csdn.net/kkkwjx/article/details/20038467 基本一样。只不过数据更强一点,把数组改大之后就能AC。我这里尝试了Java的大数,效率比我自己写的要快一些。原创 2014-03-18 22:24:22 · 674 阅读 · 0 评论 -
UVa:11795 Mega Man's Mission(状态压缩)
集合上的动态规划。状态转移方程是dp[S]=sum{dp[S^p]},其中S表示机器人集合,S^p表示S除去第p个机器人的集合,dp[S]表示消灭集合S内的机器人的顺序总数。当消灭S^p集合内机器人得到的武器可以消灭第p个机器人时,方程成立。整个过程可以用状态压缩,位运算表示集合完成。但是 判断消灭S^p集合内机器人得到的武器是否可以消灭第p个机器人 这里可以提前预处理一下,用state[原创 2014-03-18 13:42:20 · 518 阅读 · 0 评论 -
POJ:3670 Eating Together(动态规划)
题意:每次可以改变一个数字,要求使给定的数列变成单调递增或递减,求最小操作数思路:简单动规。设dp[i][j]表示以第i个数为最后一个数且数值为j时候的最优解,就递增时而言,dp[i][1]可以从dp[i-1][1]转移,dp[i][2]可以从dp[i-1][1]、dp[i-1][2]转移,dp[i][3]可以从dp[i-1][1]、dp[i-1][2]、dp[i-1][3]转移,当然还要考虑原创 2015-04-03 23:01:19 · 1028 阅读 · 0 评论 -
HDU:1024 Max Sum Plus Plus(动态规划)
题意:求最大m子段和思路:DP。状态转移方程:dp[i][j]=max(dp[i][j-1],max{dp[i-1][k],i-1dp[i][j]表示第i组以第j个数字为最后一个元素时的最大值,决策分为a[j]加到第i组第j-1个元素后和加到第i-1组第k个元素自己独立成组两种情况。#include #include #include #include using na原创 2015-03-25 11:10:53 · 428 阅读 · 0 评论 -
ZOJ:2672 Fibonacci Subsequence(动态规划+hash)
题意:在给定的数组里,寻找一个最长的序列,满足ai-2+ai-1=ai。并输出这个序列。思路:很容易想到一个DP方程dp[i][j]=max(dp[k][i])+1. (a[k]+a[i]==a[j],1dp[i][j]表示序列最后两位是a[i],a[j]时的最长长度。这个方程状态是O(n^2),转移是O(n),总复杂度是O(n^3)会超时。进一步思考会原创 2015-04-06 22:15:27 · 1876 阅读 · 0 评论 -
UVa:10051 Tower of Cubes(动态规划)
思路:LIS变形题,状态转移方程并不难想。i表示第i个立方体,j1表示正面,j2表示底面那么 dp[i][j2]=max{dp[i-1][j1]+1,dp[i][j2]} 每个立方体有两种状态用或者不用,通过颜色匹配来转移。之前一度让我纠结的就是该如何输出过程也就是构造最优解。因为它是通过颜色来转移的,而且要求输出哪个面,而且对于每个立方体不是每种颜色都可以改变。因此让我很是纠结。后来过了一段时间重新做这个题,每次使用这个立方体的时候都记录下使用的是哪个面。然后递归输出最优解,如果dp[i][j2]=原创 2013-10-31 19:07:29 · 683 阅读 · 0 评论 -
HYSBZ:1026 windy数(数位DP)
题意:求区间内windy数的个数。思路:数位DP。用递归比较好写。设f[cur][num]表示当前是第cur位,第cur+1位的数字是num时的windy数个数。显然状态转移方程是f[cur][num]=sum{f[cur-1][i]}(abs(num-i)>=2)。注意处理前导零。另外像1,2,3这种个位数也windy数。原创 2014-02-12 22:26:36 · 603 阅读 · 0 评论 -
POJ:2127 Greatest Common Increasing Subsequence(动态规划)
题意:求最长公共上升子序列。思路:此题比较容易想到一个O(n^4)的算法。具体方法是首先用两个嵌套的循环遍历数组a和数组b,当a[i]==b[j]时,寻找在数组a[1……i-1],b[1……j-1]之间,满足a[i']==b[j']且a[i']试着优化这个算法,在状态转移的时候我们要寻找一个的状态是,数值上小于当前的数组元素,而且dp[][]要最大。在上述算法中,状态转移时枚举i‘原创 2015-05-06 21:58:40 · 701 阅读 · 0 评论 -
UVa:11404 Palindromic Subsequence(动态规划)
问题可以转化成LCS输出最小字典序。用了一种很笨的办法,直接保存dp过程中的每个公共字符串,这样在两个字符不等时且dp【i-1】【j】==dp【i】【j-1】时来比较两个公共字符串的字典序来确定i,j位置的字符串。这样输出也不用倒推回去了,但是空间复杂度比较高。另外有一个问题时此题要求输出回文,这样得到的结果可以不是回文,所以取前半部分然后逆置出后半部分即是答案。用了1.2S原创 2014-03-01 14:04:56 · 694 阅读 · 0 评论 -
SDUT:2879 Colorful Cupcakes(DP计数)
题意:给3种颜色的珠子围成一个环,要求相邻两个珠子的颜色不同,问一共有多少种情况。思路:背包计数问题。可先将环看作一个链,dp[i][j][k][l],i表示以第i种颜色为尾,j、k、l分别表示三种颜色的珠子有多少个。如果是链的话很容易建立状态转移方程。环的话要考虑首尾位置,实际上就是对于答案dp[0][v0][v1][v2]这种,要减掉所有以第0种颜色开头的情况,所以只需要将dp[0][1]原创 2015-04-27 11:35:21 · 587 阅读 · 0 评论 -
UVa:10859 Placing Lampposts(树形DP)
树形DP。子问题可以分为两类,即在u为根节点且在u点放置灯时的最小灯数、u为根节点且不在u点放置灯时的最小灯数。这样用dp【u】【1】,dp【u】【0】分别表示这两种情况。用edge【u】【0/1】【1/2】表示这两种情况时同时被灯照亮一条边、两条边的个数。dp【u】【0】可以由u的所有子节点的dp【i】【1】之和转移而来,即当该结点的所有子节点都放灯时,这个点可以不放灯。同时计算ed原创 2014-03-03 13:36:18 · 684 阅读 · 0 评论 -
UVa:1292 Strategic game(树形DP)
树形DP。跟之前那个放灯的题很像,考虑每个点黑与白两种情况。涂白色的前提是子节点都是黑色。黑色可以由子节点的最小和转移而来。原创 2014-03-04 08:29:28 · 585 阅读 · 0 评论 -
SDUT:2412 Fruit Ninja I(动态规划)
题意:一个切水果游戏。每秒出现一些水果,它们都在一条线上,有好水果和坏水果,好的可以加分,坏的减分,每次连续切好水果三个以上可以分数加倍。每秒只能切一次,每切一次要间隔m秒。问最多得多少分。思路:对于每一秒的时候,可以确定连续的好水果一定会一起切,可以合并。然后用最大连续数组和求解该秒可得最优解。然后再所有的时间内进行简单动规就行了。#include using namespace原创 2015-04-13 08:00:04 · 731 阅读 · 0 评论 -
UPC:2225 The number of steps(概率DP)
题意:按题目要求问走出迷宫的期望。思路:比较明显的概率DP。#include #include #include #include using namespace std;double f[50][50];bool vis[50][50];int n;double a,b,c,d,e;double dp(int i,int j){ if(vis[i][j]) r原创 2015-04-07 21:57:23 · 488 阅读 · 0 评论 -
UPC:2541 HaHa's Morning
http://acm.upc.edu.cn/problem.php?id=2541题意:拓扑序列计数。思路:集合上的DP。floyd算法求传递闭包gl【i】【j】,可以快速判断i是否为j的前驱。dp【S】=sum{dp【S^i】}i的要求,它的前驱全部出现在S中。对于一些状态,某结点的前驱没有出现在集合中,这样的dp【S】=0 思路很巧。如果是从前往后想的话,需要每次找入度为0的点。动规是从顶往下,这样的话考虑不符合的情况就行了。原创 2014-03-24 21:54:53 · 884 阅读 · 0 评论 -
UVa:1452 Jump
约瑟夫环。只要理解了用数学办法O(n)的思路求约瑟夫环最后一个元素的算法即可。在只求最后一个元素的时候,我们每次删除元素都进行了重新编号,新编号与旧编号有一个对应关系,即f【i】=(f【i-1】+k)%i,这里f【i】表示重新编号之后该元素的编号,f【i】表示旧编号。这样很清楚最后一次删除的必定是0号元素(假设编号从0到n-1),这样利用这个关系可以推出原始序列中这个元素的编号。同理,在倒原创 2014-03-04 08:26:33 · 709 阅读 · 0 评论 -
HDU:3555 Bomb
一点没动脑。把上个题的代码改了改,先求不包含49的数个数目,然后删去就行。HDU上lld,llu似乎是不行的。用了cin和cout。#include #include #include #include #include #include #define ll unsigned long long#define INF 200000000#define MO原创 2014-02-09 21:26:20 · 578 阅读 · 0 评论 -
UVa:12105 Bigger is Better
这个题可能有非大数做法,但是我想了好久没想到什么太好的思路,所以用了大数。所以时间很慢,跑了1.4s。dp【i】【j】表示用i根火柴得到模m余j的最大数字。这样进行转移即可。过程尽量简单,因为时间复杂度比较高,一开始想用vector保存char结果超时了。注意答案为0的情况。#include #include #include #include #include #原创 2014-02-12 19:01:08 · 668 阅读 · 0 评论 -
UVa:10912 Simple Minded Hashing
还是个递推,跟之前一道题很像。注意L大于26的时候输出0.所以数组不需要开太大。#include #include #include #include #include #include #include #include #define ll long long#define INF 2139062143#define MAXN 10000//io原创 2014-02-02 20:36:18 · 565 阅读 · 0 评论 -
UVa:10616 Divisible Group Sums
怎么看都感觉像个计数类的DP,但是数太大用01背包计数明显存不下,还好是问整除,所以取余即可,这样每个数最大可以不超过20。因为有负数所以得用带余除法来取余。dp方程是dp[i][j][k]=dp[i-1][j-1][k-v[i]]+dp[i-1][j][k]dp[i][j][k]表示前i个数使用j个组成和为k时的组合种数。用了滚动数组优化了第一维。有个特别注意的地方就是k的范围,我一原创 2014-01-29 23:53:01 · 695 阅读 · 0 评论 -
UVa:11584 Partitioning by Palindromes
犯了一个SB错误。假如说读 str+1 ,那么str+1的最后一个字符的下标应该是strlen(str+1),\0是第strlen(str+1)+1。这点和读str不一样,不要搞错了。一开始想了个类似是区间dp的思路,对于给定区间分别枚举截点求它们的和,三重循环结果超时了。后来想出来了这个代码,我今天脑袋有点晕乎乎的,也说不清楚它的正确性。。dp[j][i]表示区间ji之间的最少回原创 2014-01-10 20:59:41 · 549 阅读 · 0 评论 -
UVa:620 Cellular Structure
一共三种情况,除此之外就是其他情况。另外注意如果有多种情况,要取考前的那种。给定字符串的起点和终点然后记忆化搜索即可。 #include #include #include #include #include #define ll long long#define MAXN 1005#define INF 2139062143using namesp原创 2013-12-26 21:26:12 · 565 阅读 · 0 评论 -
动态规划总结
目录(?)[+]按状态类型分编号长度动态规划区间动态规划坐标动态规划数轴动态规划5树型动态规划集合动态规划状态压缩利用动态规划思想求最值编号循环变量的迭代记忆化搜索按转移方式分存在性求一系列的分割合并点划分问题决策的分割点有序决策的分割点无序路径问题动态规划的优化迭代四边形凸性的优化动态规划总结by Amber转载 2013-08-12 10:24:06 · 801 阅读 · 0 评论 -
HDU:1003 Max Sum
最大连续子序列和的问题,之前做过好多次了。这里我用了O(n)的算法。如果和小于0,那么再加一个元素也只会比原来的元素更小,所以不如舍去前面小于0的部分。从当前元素开始求和,同时更新起点终点为当前元素。如果和大于0,那么就加上当前元素(不必考虑当前元素的正负)(和等于0执行此步操作会使最大连续子序列更长),同时更新终点为当前元素。在这过程中更新最大值,并记录对应始末位置。 O(n)的原创 2013-08-04 11:02:22 · 633 阅读 · 0 评论 -
动态规划解最长公共子序列问题
动态规划法经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题。简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加。为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法。【问题】 求两字符序列的最长公共字转载 2013-07-17 17:28:52 · 729 阅读 · 0 评论 -
UVa:10590 Boxes of Chocolates Again
这也是个整数划分的问题。数据量只有5000,O(n^2)的方法看似能行,但是由于用到大数,所以除非大数效率比较高,否则很难过掉。有了上个题的经验,用f[n]=∑(-1)^(k-1)*(f[n-k*(3*k-1)/2]+f[n-k*(3*k+1)/2]) 这个公式就行了。速度会快很多。#include #include #include #include #include原创 2014-02-27 19:52:11 · 1221 阅读 · 0 评论 -
UVa:11552 - Fewest Flops
动态规划。dp【i】【j】【k】表示前i组中,第i组以j开头以k结束时的最小组数。这样取a【j】=min{dp【i-1】【k】【j】},该组内块数为val则dp【i】【k】【q】=if k==j min{dp【i】【k】【q】,a【j】+val-1} else min{dp【i】【k】【q】,a【j】+原创 2014-03-04 22:54:13 · 676 阅读 · 0 评论 -
HDU:4651 Partition
经典的整数划分问题。使用O(n^2)的办法必超时。用这个公式可以递推出来。注意n-k*(3*k-1)/2>=0,n-k*(3*k+1)/2>=0。#include #include #include #include #include #include #include #include #include #define ll long lo原创 2014-02-27 19:41:16 · 717 阅读 · 0 评论 -
URAL:1017 Staircases
01背包计数问题。这类问题非常经典,很多问题都可以转化为背包类的计数问题。#include #include #include #include #include #include #define ll long long#define INF 2139062143#define MAXN 100005using namespace std;ll d原创 2014-02-25 22:40:17 · 584 阅读 · 0 评论 -
UVa:10910 Marks Distribution
一开始感觉可以用计数类的dp,但是自己推了推发现了个规律,于是写了一个。。。不知道为什么只有1门课而且P小于T的时候是1为什么不是0。。(后来发现了,P是及格线,T是它的得分,问的是有多少种可能。。)后来在网上看见果然可以用计数类的dp来递推:首先问题可以转换成用i个数,组成和为j的种类,dp[i][j]。然后状态转移方程dp[i][j] = dp[i - 1][j] + dp[i][原创 2014-01-30 20:54:52 · 727 阅读 · 0 评论 -
UVa:10759 Dice Throwing
简单递推。注意pow这个函数要求参数是double类型的,否则会出错。#include #include #include #include #include #include #include #include #define ll long long#define INF 2139062143#define MAXN 5000000//ios::原创 2014-02-02 18:19:22 · 602 阅读 · 0 评论 -
UVa:11258 String Partition
一开始就想到了区间dp,注意大于32位int的要设为0,这样跑了将近2s。#include #include #include #include #include #include #include #define MAXN 505#define MOD 1000000007#define INF 2139062143#define ll long lo原创 2014-01-19 13:05:32 · 685 阅读 · 0 评论 -
HDU:2089 不要62
数位dp。学习了这篇PPT。http://wenku.baidu.com/link?url=mUxdsYomenU-e9SFVPacVtXysemiQA4KnP1EldVuYaB8ECiaLQN4VIAEc19MmHQWQeFqUrU4oFpsX2J1LvrAeoJyAmDYdwMODM8mm3ph327注意是右边是开区间。用到了区间的分解,说得很详细。#include #incl原创 2014-02-09 19:54:08 · 567 阅读 · 0 评论 -
UVa:1424 Salesmen
果然是简单DP。dp【i】【j】表示第i个字符为j时的最小修改点数。这样可以通过i-1与i之间j和k是否相邻或者相同来转移,如果序列中第i个数字与k不同,则要加一。#include #include #include #include #include #include #include #include #include #define ll lo原创 2014-03-05 19:12:06 · 743 阅读 · 0 评论