UVa 1630 区间DP Folding】的更多相关文章

一个字符串如果能简写,要么是重复多次,按题中的要求简写:要么是左右两个部分分别简写后再拼起来. dp(i, j)表示字串(i, j)所能被简写的最短的字符串. 判断一个字符串是否为周期串以及求出它的周期用的KMP算法. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> using namespace std…
题意: 给一段字符串成段染色,问染成目标串最少次数. SOL: 区间DP... DP[i][j]表示从i染到j最小代价 转移:dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]); CODE: BZ: /*================================================================= # Created time: 2016-03-28 21:10 # Filename: uva4394.cpp # Desc…
uva 紫书例题,这个区间dp最容易错的应该是(S)这种匹配情况,如果不是题目中给了提示我就忽略了,只想着左右分割忘记了这种特殊的例子. dp[i][j]=MIN{dp[i+1][j-1] | if(match(i,j) , dp[i][k]+dp[k+1][j] | i<=k<=j .}注意初始化dp[i][i]=1,表示1个字符最少需要一个才能匹配,dp[i+1][i]=0,因为可能只有两个字符使得i+1>j-1,我们可以认为中间是空字符已经匹配了. 打印路径利用了递归,很巧妙,lr…
区间dp,可以以一个区间为状态,f[i][j]是第i个切点到第j个切点的木棍的最小费用 那么对于当前这一个区间,枚举切点k, 可以得出f[i][j] = min{dp(i, k) + dp(k, j) | i < k < j} + a[j] - a[i](这一段的长度,也就是这一刀的费用) 然后记住要人为的加入两个切点头和尾 然后因为长区间依赖于短区间,所以要从短区间渐渐推到长区间. 如果是记忆化搜索,那么就是左端点和右端点不断减少,递归,满足. 如果是递推,那么注意区间长度要不断变长,具体看…
这个题目蛮有新意的,一度导致我没看透他是区间DP 给一个0-L长度的木板,然后给N个数,表示0-L之间的某个刻度,最后要用刀把每个刻度都切一下 使其断开,然后每次分裂的cost是分裂前的木板的长度.求整个分开之后的最小cost. 当时下意识就想到类似花瓶插花问题,即dp[i][j],表示第i个事物放在第j次动作来的最小代价,但是当我写起来发现很麻烦,我是以刻度点来表示的i,结果发现处理起来相当麻烦,因为实体实际是一块一块的小木板,以点作为转移变量 不仅要加诸多限制,而且加完后发现会互相矛盾,原因…
https://vjudge.net/problem/UVA-10891 给定一个序列x,A和B依次取数,规则是每次只能从头或者尾部取走若干个数,A和B采取的策略使得自己取出的数尽量和最大,A是先手,求最后A-B的得分. 令 f(i,j)表示对于[i,j]对应的序列,先手可以从中获得的最大得分,那么答案可以写为  f(i,j)-(sum(i,j)-f(i,j)),也就是 2*f(i,j)-sum(i,j) 下面讨论f(i,j)的写法,显然递归的形式更好表达一些,为了防止重复的计算使用记忆化搜索.…
很明显带有博弈的味道.让A-B最大,由于双方都采用最佳策略,在博弈中有一个要求时,让一方的值尽量大.而且由于是序列,所以很容易想到状态dp[i][j],表示序列从i到j.结合博弈中的思想,表示初始状态i->j情况下,先手能获得的最大分数.后手能获得的就是sum[i][j]-dp[i][j].接下来枚举先手选取的是两端的哪一段即可. #include <iostream> #include <cstdio> #include <cstring> using name…
当前区间f(i, j)分两种情况,一种是s[i]于s[j]符合要求,那么可以转移到f[i + 1][j - 1] 这样答案只会更小或者相等 第二种是直接分成两个部分, 即f[i][j] = f[i][k] + f[k + 1][j],这个时候要取min 同时要注意第一种情况未必是最优的,要从一二两种情况里面取最优值 然后输出方面,按照答案反推,如果当前状态刚好等于其中一种情况,那么就递归下去,边界是 一个字符的时候输出两个字符. 另外学会用fgets,不用gets.fgets头文件cstdio,…
经典博弈区间DP 题目链接:https://uva.onlinejudge.org/external/108/p10891.pdf 题意: 给定n个数字,A和B可以从这串数字的两端任意选数字,一次只能从一端选取. 并且A B都尽力使自己选择的结果为最大的,可以理解成A B每一步走的都是最优的. 如果A先选择,则A B差值最大是多少. 分析: 总和是一定的,所以一个得分越高,另一个人的得分越低.当前状态总是最开始的状态的一个子状态. d(i,j): 先手取 i ~ j 最优策略下,得分最大值. d…
// 区间DP+next求循环节 uva 6876 // 题意:化简字符串 并表示出来 // 思路:dp[i][j]表示 i到j的最小长度 // 分成两部分 再求一个循环节 #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <cmath> #include <map>…