ACM.DP
slowlight93
这个作者很懒,什么都没留下…
展开
-
poj 1651 Multiplication Puzzle(区间DP)
题意: 。。。 思路: 区间DP入门题int n, ai[N+5], dp[N+5][N+5];int main() { scanf("%d", &n); for (int i = 0; i < n; ++ i) scanf("%d", ai + i); const int INF = INT_MAX / 10; for (int len = 3; len <=原创 2015-09-07 00:56:52 · 380 阅读 · 0 评论 -
hdu 5115 Dire Wolf(DP进阶)
题意: 。。。 思路: 很典型的O(n3)的区间dp,类似矩阵链乘,能量项链这种。 不过肯定有些微区别。 我们尝试用类似的方程来解决,注意到在前两个问题中,存在一个固定的首尾。。 所以设计dp[i][j]dp[i][j]为除了首尾,消灭中间的狼的最小代价。。 添加0,n+1这两条虚拟的狼。。 答案就是dp[0][n+1]dp[0][n+1]LL a[Maxn+5], b[Maxn+5原创 2015-04-23 20:25:42 · 669 阅读 · 1 评论 -
srm 305 div2 1050(bfs中级)
题意: 背景赞一个! 经典的羊和狼乘船过河问题。这里换成了牧师和野人。。 思路: 基本的bfs即可。。不需要技巧。。struct St { int m, c, b, cnt;};int f[105][105][2];class Cannibals{ public: int check(int lc, int lm, int rc, int rm) {原创 2015-04-07 20:37:08 · 375 阅读 · 0 评论 -
zoj 3329 One Person Game(概率DP基础)
题意: 。。。 思路: E[i]E[i]为当前分数为i时,到游戏结束时掷骰次数的期望。 E[i]=∑Pk∗Ei+k+P0∗E0,P0=1/(k1+k2+k3)E[i] = \sum{P_k*E_{i+k}}+P_0*E_0, P_0 = 1/(k1+k2+k3) 我们要求的是E[0],,边界是E[j]=0,j>nE[j] = 0, j>n 假设E[i] = ai * E[0] + bi原创 2015-04-05 20:46:48 · 389 阅读 · 0 评论 -
zoj 3640 Help Me Escape(概率DP基础)
题意: 。。。 思路: 题面给了个大大的公式可能会吓到人 = =。。 不过看懂题就没什么了。 普通的概率dp,甚至不用变换方程式 = =! Ei=P∗(∑(Ei+cj,i<=cj+1)+tj,i>cj)E_i = P*(\sum{(E_{i+c_j, i<=c_j}+1})+t_{j,i>c_j}) 边界是E[i],i>max{cj}E[i], i>max\{c_j\}int n, f原创 2015-04-05 22:15:06 · 456 阅读 · 0 评论 -
hdu 4035 Maze(概率DP进阶,树形DP)
题意: 给你一棵树(也可能是森林) 站在每个节点时 1)有ki的几率回到节点1 2)有ei的几率离开 3)随机移动到一个相邻的节点 最开始在1,求离开需要移动的次数的期望。 思路: 一开始打算直接上方程然后求解线性方程组来着。。 后来发现判断无解难以处理(1e5的数据。。) 1)方程很容易写出来,注意我们是在树上进行dp,所以最好区分father和children 2)边界是叶原创 2015-04-05 21:04:24 · 432 阅读 · 0 评论 -
poj Round Numbers 3252(数位dp进阶)
题意: 统计区间内0的位数大于等于1的位数的二进制数。 ex:[1, 4]中有2(10), 4(100) 思路: 数位dp,f[pos][前面0的个数][前面1的个数]f[pos][前面0的个数][前面1的个数]是要记忆化的状态int d[35], f[35][35][35];// limit:是否达到上界// nolead: 没有前导0int dp (int pos, int lim原创 2015-04-03 14:36:17 · 486 阅读 · 0 评论 -
srm 653 div2 1000(dp)
题意: 一个序列的值定义为其差分结果的绝对值之和。例如, {1, 2, 3} 值为 abs(2-1) + abs(3-2) = 2 现在有一个长度大于等于1的序列,要求把它分成两个子序列,使得两个序列的值之和最小。 思路: 一开始想残了。。 打算用f[A唱最后一个音][B唱的最后一个音]f[A唱最后一个音][B唱的最后一个音]这个状态,显然这是个n3的复杂度。。。 其实,我们只要考虑f[原创 2015-03-17 22:36:56 · 505 阅读 · 0 评论 -
codeforces 55D Beautiful numbers(数位dp进阶)
题意: 求[L,R]之间能整除自己每一个非0位的数的个数。 思路: 1)1-9的lcd是2520 假设一个数 k*2520 + m, i是2-9中的某一位(1就不考虑了) (k*2520 + m)%i = m%i 所以我们在dp的时候,保留对2520的余数就好了,然后用bitset(也有不用bitset用最小公倍数的)来记录哪些数字出现过。 不过这个方法是有些暴力了,好在cf比较和谐。原创 2015-03-19 01:54:34 · 555 阅读 · 0 评论 -
hdu 3652 B-number(数位dp)
相当于对 求[1, n]中包含13的数字 这个问题多加了一个限制,要求被13整除。于是改写原来的状态 f(k, i, j, l) 前面两维依旧,以i开头位数为k。j取1 or 0,表示是否包含13,l 取 [0, 13) 表示MOD13后余数为l。在计数的时候,还要维护一个变量,用来表示前面的数位是否包含13,因为这里不像只需要判断是否包含13的情况,现在不能直接break。同时可以维原创 2014-11-02 02:09:11 · 410 阅读 · 0 评论 -
srm 304 div2 1000(环形DP进阶,几何)
题意: 给你一个多边形。(顺时针给出顶点)你可以选择一些互不相邻的顶点来移动,使得移动后的多边形面积最大。 思路: 这道题的贪心思路是错的,因为不存在最优性质,因为你可以连续不选一些点来获取更大的解。 先考虑只移动一个顶点是怎样最优。v1, v2, v3相邻,现在移动v2。问题变成了怎样使三角形v1v2v3的面积最大,很显然应该沿着高线移动。最大增加量就是 |v1v3|*1/2 现在定义d原创 2015-03-29 23:54:02 · 540 阅读 · 0 评论 -
codeforces 13C Sequence(排序,DP)
题意: 一个整数序列,每次操作可以对其中一个数加1或者减1。 求把这个序列变成非减序列所需的最少操作次数。 思路: 设原序列是A,目标序列是B 那么容易知道,B中的元素一定是A中元素的子集。 尝试用f[i][j]f[i][j]来表示,将前i个数变成非减序列,且最后一个元素的高度为a[j],1<=j<=ia[j], 1<=j<=i的最少操作 但是很快发现这个方程是错误的,因为j的取值范围原创 2015-03-22 22:48:51 · 754 阅读 · 0 评论 -
srm 306 div2 1000 (字符串dp,进阶)
题意: 有一个原串s和一个目标串t。 向s插入一些串,这些被插入的串被称为block,使得s与t相同。 求最少插入多少block达到目标。 思路: O(n3)的做法:设i,j分别是s,t中的下标。那么方程描述为:把从i开始的s的字串变成从j开始的t的字串最少插入的block。 决策有两种,分别对应s[i]=s[j]和s[i]!=s[j]: 1)相等:转移到dp(i+1, j+1) 2原创 2015-04-08 18:18:47 · 400 阅读 · 0 评论 -
srm 308 div2 1000(DP, 离散背包+连续背包)
题意: n个背包,有的可以拆分,有的不能拆。给定Weight求最大值。 思路: 离散和连续的分别求一下。然后枚举i,W-iclass TreasuresPacking{ public: double maximizeCost(vector <string> treasures, int W) { vector<node> dis原创 2015-04-09 00:53:51 · 1075 阅读 · 0 评论 -
poj 2955 Brackets (区间dp)
题意: 。。。 思路: 区间DP入门题char str[N+5];int dp[N][N];inline bool match(int x, int y) { return str[x] == '(' && str[y] == ')' || str[x] == '[' && str[y] == ']';}int main() {#ifdef _LOCA_ENV_ freo原创 2015-09-07 00:32:41 · 319 阅读 · 0 评论 -
light oj 1422 Halloween Costumes (区间DP)
题意: 。。。 思路: 跟着kuangbin的blog开始刷区间DP。。 开始也是对这道题没想法。。 不对,联系了一下 hdu 2476 String painter 这道题。。 发现思考模式是一样的。。 dp[i][j]dp[i][j] 照例是区间 i,j 的最小代价 考虑从 dp[i+1][j]dp[i+1][j] 转移过来 费用就是 i 与 i+1 穿的衣服是否相同 dp[原创 2015-09-07 01:36:23 · 601 阅读 · 0 评论 -
zoj 3537 Cake (区间DP x 最优三角形剖分)
题意: 。。。 思路: 思路可以看这里区间DP的顺序目前遇到比较多的有两种,无论哪种,保证算大区间时,所包含的小区间都已经算完大概就行了。。 1)// 第一层 loop 枚举长度for (int len = 1; len <= n; ++ len) for (int i = 0; i + len - 1 < n; ++ i)2)// 直接枚举端点for (int j = 0; j原创 2015-09-05 23:13:57 · 413 阅读 · 0 评论 -
hdu 2476 String painter(区间DP)
题意: 给A,B两个串,|A| = |B| 一次操可以把 A 的一个字串刷成同一种字符。 求最少多少次操作可以把 A 变成 B。 思路: 很经典的一道区间DP。。 首先观察到,如果 B[i]=B[j]B[i] = B[j],那么 i, j 可以由一次操作得到。 所以由空串得到 B 的方程 dp[i,j]=min(dp[i+1][j]+1,dp[i][k−1]+dp[k][j] and原创 2015-09-04 23:36:09 · 515 阅读 · 0 评论 -
hdu 4352 XHXJ's LIS(数位dp进阶,LIS, 状态压缩)
题意: 一个数的power value是这个数中LIS的长度,比如12331是3,1234是4。。 现在要求一个区间[L, R]中的power value为k的数的总数。 思路: 如何表示dp到pos, 前一个为pre时的状态? 结合LIS的性质,我们想到了用bitset来表示当前LIS的状态,10个二进制位。 其实根本没有用到pre,省去此维,采用状态f[pos][state]就行了。原创 2015-03-17 01:38:52 · 595 阅读 · 0 评论 -
HDU 5378 Leader in Tree Land (概率dp,进阶)
题意: 给一棵有n个节点,根为1的树的每个节点赋一个值 1-n 的唯一的值。一个子树的代表是其中最大的节点。则一共有m个代表,求m=k的方案数。 思路: 多校题。。这样的dp还是不太会。。 1) u是一个代表 等价于 u是以他为根的子树的最大值 2)有k个代表 等价于 有且只有k个子树,根为该子树中的最大值 sz[u]表示sz[u]表示 u的子树大小 dp[i][j]dp[i][j]表原创 2015-08-12 15:15:08 · 747 阅读 · 2 评论 -
codeforces 285E Positions in Permutations(DP+容斥,hard)
题意: 定义1~N构成的排列 p(1)p(2)…p(N) 满足 abs(p(i) - i) = 1 的称之为 good position 统计有K个good position的排列数思路: 每个位置要么是 good position,要么不是。。 我们可以先考虑占坑,有N个坑,我们先占r个(0<=r<=N)作为good position,其余的数任意排列,这样我们就知道 good posi原创 2015-05-19 01:02:06 · 1182 阅读 · 0 评论 -
srm 656 div2 1000(dp+组合)
题意: 从所有的N排列里面([1….N]),数出满足p(k)<p(k+1)p(k)<p(k+1)当且仅当k在集合s中的排列数目。 例如:N=5,s = {3} 则 除了 p(3) < p(4),其它位置的数都要小于后继。 思路: 首先考虑1可以怎么放,用lessThan(i)表示p(i)是否小于p(i+1) 则可以放1的位置是(i == 0 || !lessThan(i-1) ) &&原创 2015-05-07 17:23:47 · 562 阅读 · 0 评论 -
srm 181 div1 1000(状压dp)
题意: 克洛人。。打败n个Boss通关。每个Boss掉一把装备,每把装备对n个Boss有不同伤害值。初始有一把对所有Boss伤害值都为1的枪。 n no more than 15,求最少攻击次数 思路: 用最多15个bit来表示现在拥有的武器。然后可以用记忆化搜索解决。 转移的时候,先枚举被打败的boss,再枚举费用,即使用哪把武器攻击次数最少。int dp[32768], shots[1原创 2015-05-03 19:06:55 · 562 阅读 · 0 评论 -
codeforces 543A Writing Code(dp降维优化,完全背包思想)
题意: 。。。 思路: 首先考虑最直接的三维方程 dp(i, j, k) 表示前i个程序员写了j行代码bug不超过k dp(i,j,k)=∑dp(i−1,j−r,k−r∗a[i]),第i个程序员写了r行代码dp(i, j, k) = \sum{dp(i-1, j - r, k - r * a[i])}, 第i个程序员写了r行代码 我们可以换种视角优化这个方程 1)第i个程序员没写代码原创 2015-05-08 12:34:16 · 1045 阅读 · 0 评论 -
srm 655 div2 1000(DP进阶,枚举状态)
题意: 给一个数组a,长度n。对应一个n位数,可以有前导0。 有N个问题,每个问题对应着一些数位,即问题i对应第i个bit为1的数位(从最低位开始)。 对于每个问题,要求把对应的数位连起来构成的数,mod9结果为0。 问有多少个满足条件的数。 思路: 首先mod9有个很重要的性质,即x mod 9 = (x所有数位之和)mod 9 对于一个问题,简单dp就可以解决。 但是再来一个问题原创 2015-04-14 22:45:43 · 485 阅读 · 0 评论 -
srm 301 div2 1000 (经典dp, 括号匹配)
题意: 一个长度为偶数的字符串,只包括(, ), [, ], {, }这几种字符, 并且长度为偶数。 现在求最少修改几个字符可以使该串成为一个整齐的串。 1)空串是整齐的。 2)如果s是整齐的, (s), [s], {s}, 也是整齐的。 3)连起来的整齐串也是整齐的 思路: 对于一个串(l, r),我们可以这样枚举子状态。 1)脱去首尾。 2)分成(l, i), (i+1, r)原创 2015-03-29 15:01:10 · 556 阅读 · 0 评论 -
codeforces 118D Caesar's Legions(DP进阶)
题意: 有n1个骑兵,n2个步兵,排成一列。 求满足下列条件的排列数。 1)连续的骑兵不超过n1 2)连续的步兵不超过n2 思路: 一开始使用状态f[i][j][k][2]f[i][j][k][2]第四位为0表示最后是骑兵,1则是步兵 i, j:骑兵,步兵个数 k:最后连续的一段不超过k 其实第三维是冗余的,因为我们只要在转移的时候保证最后一段不超过k就好了,因此可以去掉第三维。i原创 2015-03-29 01:38:22 · 895 阅读 · 0 评论 -
hdu 2844 Coins(DP, 背包)
题意:硬币的面值 A1....An, 每种面值持有数 C1....Cn, 求 [1, m] 中能够凑出的面值数。多重背包附加二进制优化buff。。。Ai * Ci >= m 的情况用完全背包处理。。。挺好的一道题,两种背包都考了还加个优化。。。#include#include#include#include#include#include#include#includ原创 2014-11-30 17:44:14 · 444 阅读 · 0 评论 -
hdu 2955 Robberies(概率,dp)
题意:。。思路:tot 物品总价值f[i][j] 前i个物品价值为j时最小的概率选择i得到的新概率: p[i] * (1-f[i-1][j - v[i]]) + f[i-1][j - v[i]]//#include#include #include #include #include #include #include #include #include #i原创 2015-02-06 12:10:38 · 432 阅读 · 0 评论 -
uva 11021 Tribles (概率,递推)
题意:略。。白书上经典的概率题思路:f(i) 表示一开始有一个毛球,i天后死亡的概率。#include#define SPEED_UP iostream::sync_with_stdio(false);using namespace std;#define rep(i, s, t) for(int (i)=(s);(i)<=(t);++(i))#define urep(原创 2014-12-28 14:04:10 · 474 阅读 · 0 评论 -
poj 1179 Polygon(DP)
题意:给出一个有n个节点的环,节点有整数值,边是乘号*或者加号+。一开始去除一条边,然后每次选一条边,合并该边所连节点,知道最后只剩一个节点。求所能得到的最大值。思路:类似矩阵乘法的O(n3) dp, 注意1:因为是环形,所以要取mod,注意2:保存min值,因为乘法运算。#include #include #include #include #include #include原创 2014-12-24 17:37:24 · 435 阅读 · 0 评论 -
poj 1159 Palindrome(lcs类似dp)
题意:问一个字符串最少插入多少个字符可以将其变成回文串。思路:f(i, k) 为 从i开始长度为k 的字串变成回文串最少需要插入字符数。看见discuss明白了这个口以看作 原串长-正逆串lcs。。不过开二维数组会mle, 不过貌似空间减半就可以了,所以直接有人用压缩矩阵或者改用short。。我用f1,f2分别保存上个和上上个状态,空间消耗5000*2。。//#includ原创 2015-01-29 23:51:15 · 397 阅读 · 0 评论 -
hdu 4336 Card Collector(概率dp, 容斥原理)
题意:相当于盒子里有n个球,每个球被取到的概率为pi, 问取到全部n个球的次数期望是多少?概率dp:题解参见:http://www.cnblogs.com/zhj5chengfeng/archive/2013/03/02/2939601.htmls是用来表示已取到的球的二进制集合,i 是属于集合s的球,k不属于s,s‘是将k加入s得到的集合,即 s’ = s | (1例原创 2014-11-26 01:22:52 · 573 阅读 · 0 评论 -
noip2012普及组 摆花(DP)
题意:有n种花,每种花有ai盆,原创 2014-11-14 01:36:19 · 2116 阅读 · 0 评论 -
hdu 2089 不要62(数位dp)
先预处理出原创 2014-11-01 17:20:20 · 421 阅读 · 0 评论 -
poj 1187 陨石的秘密(字符串DP)
题意是这样的:定义SS串:1)空串是SS原创 2014-11-10 23:08:32 · 1342 阅读 · 0 评论 -
uva 1401 Remember the Word(Trie dp)
s0s1F[i] 以i结尾原创 2014-08-29 21:09:37 · 489 阅读 · 0 评论 -
codeforces 505C Mr. Kitayuta, the Treasure Hunter(DP)
题意:数轴上点[0, 30000]。先从 0 跳到 d, 以后每次跳的步数是 {prev-1, prev, prev+1}。跳到某个点上可以得到相应的value,求可以得到最大的value。思路:n, d 最大都是30000, 所以 min_step >= d-246, max_step所以方程 f[i, j] 当前在 i, 前一次跳的长度是 j注意要把 [min_step,原创 2015-01-22 17:45:55 · 880 阅读 · 0 评论 -
SRM 649 div2 500(dp)
题意: 给一个集合,最开始只有一个正整数N。。 求最少使用多少轮可以把集合变成空集(数字变成0则从集合消去) each turn, 对集合中每个数可以进行两个操作: 1) 分成两个(不能分出0) 2)减一 思路: 记忆化搜索 边界:f(n, 0) = nclass CartInSupermarketEasy{ public: int dp(int n, i原创 2015-02-12 20:07:35 · 468 阅读 · 0 评论 -
codeforces 213C Relay Race(DP基础,棋盘路径)
题意: n×n的矩阵a, −1000<=aij<=1000-1000 <= a_{ij} <= 1000 求从(1, 1)到(n,n)的两条路线(经过的格子可以重复),路线上的数值和最大,每个元素只能被取一次。 思路: 容易得出一个自然的状态表示是第k条对角线上取(k-i, i)和(k-j, j)的最大值。 用刷表法比较容易管理边界。k, i, j // 可行状态for (int si原创 2015-03-29 01:28:13 · 661 阅读 · 0 评论