随笔分类 -  DP

摘要:把数位dp写成记忆化搜索的形式,方法很赞,代码量少了很多。下面为转载内容: apositiveintegernumberisbeautifulifandonlyifitisdivisiblebyeachofitsnonzerodigits.问一个区间内[l,r]有多少个Beautiful数字范围9*10^18数位统计问题,构造状态也挺难的,我想不出,我的思维局限在用递推去初始化状态,而这里的状态定义也比较难跟pre的具体数字有关问了NotOnlySuccess的,豁然开朗Orz一个数字要被它的所有非零位整除,即被他们的LCM整除,可以存已有数字的Mask,但更好的方法是存它们的LCM{dig. 阅读全文
posted @ 2013-06-17 21:54 AC_Von 阅读(3098) 评论(0) 推荐(0) 编辑
摘要:跟 HDU 4057Rescue the Rabbit差不多的AC自动机+dp,比赛的时候被虐成傻逼了!!!999的状态不多,直接状态压缩就行。dp[i][ACstatus][status] 到字符串第i位置,在AC自动机上状态为ACstatus,包含到999的状态为status。更新了一下自动机的模板。。。Orz简洁写法View Code #include <iostream>#include <cstdio>#include <cmath>#include <vector>#include <cstring>#include &l 阅读全文
posted @ 2013-04-01 15:34 AC_Von 阅读(433) 评论(0) 推荐(0) 编辑
摘要:先保存一下代码,回头写题解。View Code #include <iostream>#include <cstdio>#include <cmath>#include <vector>#include <cstring>#include <algorithm>#include <string>#include <set>#include <functional>#include <numeric>#include <sstream>#include <st 阅读全文
posted @ 2013-03-23 18:48 AC_Von 阅读(354) 评论(0) 推荐(0) 编辑
摘要:250...500...1000 比赛的时候没思路。倒是想到一种trick,想cha人来着,后来发现房间里没有人提交。。。只想到了预处理出从一个点到另一个点走m步所要用到的情况数,发现dp空间复杂度太高。今天看了一下别人怎么预处理的,我还是太嫩啊。。。dp[dx][dy][m]表示走m步坐标移动了(dx, dy)所有的情况数。记忆化搜索一下。const int MAXN = 55;const int MOD = 1e9+7;int dp[MAXN][MAXN][MAXN];int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};class Wol. 阅读全文
posted @ 2013-03-21 19:55 AC_Von 阅读(356) 评论(0) 推荐(0) 编辑
摘要:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2412 实验证明,被小错误搞死的感觉太不爽了!! 这题是去年省赛的题,今天重新做了一下。我了个去。被俩二b错误搞死了。!! 思路:先预处理出某一秒如果切的话能得到的最大值。然后单调队列优化一下就行。 View Code #include <iostream>#include <cstdio>#include <cmath>#include <vector>#include <cstring& 阅读全文
posted @ 2013-03-19 20:50 AC_Von 阅读(704) 评论(5) 推荐(0) 编辑
摘要:250pt 和 500pt都是简单题,500pt暴力就可以。。。1000pt:题意:给一棵树,求这棵树中不同子树的个数。解:f[i]表示以i点为根节点所包含的子数的个数。f[i] *= (f[j] + 1) 其中i -> j有边相连,+1表示不选以j为根的这棵子树;dfs;int mp[60][60];bool vis[60];LL ans;class CentaurCompanyDiv2 {public: LL dfs(int u) { int i; vis[u] = true; LL cnt = 1; for(i = 1; i ... 阅读全文
posted @ 2013-02-19 10:01 AC_Von 阅读(208) 评论(0) 推荐(0) 编辑
摘要:斜率优化其实就是把每个状态看上直角坐标系上离散的点抽象出x,y 表示斜率 (y2 - y1) / (x2 - x1) 于一个关系状态i个函数的关系,然后维护点见斜率的上凸性或者下凸性。具体的情况要看于i有关的函数的单调性。斜率优化dp基本都是和单调队列结合使用的。 POJ 1180这题,状态转移方程开始只想到正向推O(n^2)的复杂度,但是正向推有两个不确定量,不能优化。后来看解题报告才知道可以从后往前推。sumT[i]表示从i到n的任务所需要的时间总和,sumF[i]表示从i到n的费用系数总和,dp[i]表示对于从i到n的任务安排的最优解: dp[i]=min(dp[j]+(sunT... 阅读全文
posted @ 2013-01-21 18:45 AC_Von 阅读(1252) 评论(0) 推荐(0) 编辑
摘要:四边形不等式优化动态规划原理:1.当决策代价函数w[i][j]满足w[i][j]+w[i’][j’]<=w[I;][j]+w[i][j’](i<=i’<=j<=j’)时,称w满足四边形不等式.当函数w[i][j]满足w[i’][j]<=w[i][j’] i<=i’<=j<=j’)时,称w关于区间包含关系单调.2.如果状态转移方程m为且决策代价w满足四边形不等式的单调函数(可以推导出m亦为满足四边形不等式的单调函数),则可利用四边形不等式推出最优决策s的单调函数性,从而减少每个状态的状态数,将算法的时间复杂度由原来的O(n^3)降低为O(n^2). 阅读全文
posted @ 2013-01-21 10:31 AC_Von 阅读(1560) 评论(0) 推荐(0) 编辑
摘要:题意:给一个长度为N(N < 50000)的序列,求这个序列中长度为5的递增子序列的个数。思路:对于长度为5的子序列,先考虑长度为1的子序列,第i个位置以i结尾长度为1的子序列个数为1。第i个位置以i结尾长度为2的子序列个数为i之前并且小于a[i]的长度为1的子序列的个数。同理,第i位置长度为3的子序列个数为i之前小于a[i]的长度为2的子序列的个数。。。依次往后推。比如原序列为:(1, 2, 4, 6, 3) 推: -> (1, 1, 1, 1, 1)1 -> (0, 1, 2, 3, 2)2 -> (0, 0, 1, 3, 1)3 -> (0, 0, 0, 1 阅读全文
posted @ 2013-01-18 16:52 AC_Von 阅读(945) 评论(0) 推荐(0) 编辑
摘要:动态规划需要用数据结构优化的动态规划poj2754,poj3378,poj3017四边形不等式理论、斜率优化poj1160,poj1180,poj3709较难的状态DP、插头DPpoj3133,poj1739,poj2411、poj1763 需要用数据结构优化的动态规划 POJ 3017 题意:给一个长为N的序列A,从中可以画出k个子序列,S1,S2,... ,Sk。求这些子序列中sigma(max(S[i]))最小。(1<=i<=k)并且满足sigma(S[i])<= M;解:转移方程,f[i] = min(f[j] + max(num[j+1...i])),这是一个很朴素 阅读全文
posted @ 2012-12-21 16:28 AC_Von 阅读(810) 评论(0) 推荐(0) 编辑
摘要:比赛的时候真心没想出来什么好的dp方法。。。蛋疼!整个比赛脑子发懵。。。!dp[i][j]表示到第j个人,i到j是一个group时说真话的最大人数。num[a][b]统计出说前面有a个,后面有b个的人的个数,当然,不超过n - a - b;dp[i][j] = max{dp[k][i]} + num[i][n-j];ans = max{dp[k][n]};ps:蛋疼的java.util.Arrays.fill(),妹的!内部函数就是一个for循环,只能初始化一维数组。。。表示以后再也不用了。。。import java.util.*;public class Main { /** ... 阅读全文
posted @ 2012-09-17 19:37 AC_Von 阅读(264) 评论(2) 推荐(0) 编辑
摘要:对于这个解法,网上题解一大堆。不过觉得还是算导官方给的解答好些,简洁又清楚。。。大概总结一下(不是翻译)=.=首先是排序。然后确定状态 f[i][j] (i >= j, i == j表示的只有n这个点) 表示 从i到1严格从右往左走然后再从1严格从左往右走到j 这样两条路径的最小值,当然[1, max(i, j)]区间上所有的点都是被访问过得。存在两种状态 :1: j < i - 1;dp[i][j] = dp[i-1][j] + Dis(i, i - 1);2: j == i - 1;dp[i][j] = min{dp[i][j], dp[j][k] + Dis(k, i)} / 阅读全文
posted @ 2012-09-15 16:16 AC_Von 阅读(1523) 评论(1) 推荐(0) 编辑
摘要:题意很纠结。。。说的是1...n这些人登台,每个人有个吊丝值D[i],如果i号人第k个登台,那么他的愤怒值就是(k-1)*D[i]。现在有一个栈,可以先把i前边的人依次次进栈,然后让第i号人登台,然后在选择是栈里的同学登台还是i以后的同学登台,这样很多种情况会得到很多总愤怒值。求最小的总愤怒值。。。。 n<=100,暴力肯定不行。3^100....只能考虑dp,(贪心直接忽略-_-!)。想了半天一直在考虑怎么保存被访问的状态。。。所以从昨天晚上到今天一直没什么进展,无奈看了看解题报告。。设计思路确实很巧妙。。。 dp[i][j]表示区间[i, j]的最优值,设[i, j]上i是第k个访. 阅读全文
posted @ 2012-09-12 20:57 AC_Von 阅读(263) 评论(0) 推荐(0) 编辑
摘要:今年天津赛区网络赛的一道题,比赛的时候跟强哥讨论了一下,他的思路很明确,然后就让他去写了。。。赛后偶翻了翻这个题。。。额,还不错的状态dp把。。。就是让我给写搓了。。。贡献n次wa。。。 题目是给一下点之间的花费,构成一个图(图不是很大,最多100*100)。然后指定一些必须访问的点。并且这些点上有一个先花费Di再收入Ci的过程,问能否实现访问所有这些点。。。因为指定的点数最多为15,加上1号点最多才17,所以直接用状态压缩就可以。先用floyd找出任意两点间的最小花费。然后dp[status][pos]表示当前状态为status并且最后访问的点为pos时,所有的资金数。最后找一个dp[... 阅读全文
posted @ 2012-09-11 21:26 AC_Von 阅读(238) 评论(0) 推荐(0) 编辑
摘要:终于把这题搞出来了。。。前后看了半一星期。比赛堆积的题目在减少。。。加油! 数位dp,f[i][sum][mod][res]表示前i位,和为sum,模为mod,sum%mod结果为res的状态个数。f[i+1][sum+k][mod][(res*10 + k)%mod] += f[i][sum][mod][res];予处理出所有的f[i][sum][mod][res], 然后从高到低逐位统计。比如当前位为a_i,则枚举当前位为0...(a_i-1) 这些数,i位往后的数的所有状态已经预处理出来了。。。所以出现 %mod == 0的情况直接累加就可以。。。最后单独处理一下最低位。。。 1... 阅读全文
posted @ 2012-08-28 10:39 AC_Von 阅读(765) 评论(0) 推荐(0) 编辑
摘要:题目意思是给一个原点坐标,然后再给n个点坐标,每个点有一块砖头,要求把这n个砖头搬到原点。每次最多搬两块,并且走一条路用的时间为坐标距离的平方。求最短时间。n<=20而且要输出方案,多种方案的话按最小字典序输出。。。解:如果不需要输出方案的话,那这题就很容易 了。。。f[i]表示到达i状态的最小时间。一个没有搬的砖头j,f[i|(1<<j)] = min{f[i] + 2*dis(a[j], O)};再枚举一个没有到达的状态k,f[i|(1<<j)|(1<<k)] = min{f[i] + dis(a[j], O) + dis(a[j], a[k]) 阅读全文
posted @ 2012-08-27 20:08 AC_Von 阅读(420) 评论(0) 推荐(0) 编辑
摘要:不错的题,做了两次。两次感觉不一样,第一次那叫一个费劲啊。。。看了一天的解题报告,才大概理解怎么回事,这次做完好好写写总结吧。开始想到的状态有sum[i]表示以i为根的子树走遍所有的字节点的值,leaves[i]表示以i为跟的子树的叶子节点数。显然是错误的。。。好多状态表示不出来。后来有考虑分回到i节点和不回到i节点这两种状态。但还是设计不出来,最不能确定的就是一个顺序问题。无奈翻了一下以前看的资料。发现一个没有想到的贪心方法。。。。success[u]表示u为根的子树上,成功找到房子的步数和fail[u]表示u为根的子树上,找不到房子的步数和leaves[u]表示u为根的子树上,叶子节点.. 阅读全文
posted @ 2012-08-20 16:07 AC_Von 阅读(770) 评论(0) 推荐(0) 编辑
摘要:那道题目看着好多状态。。。leader, speed, energy, distance,还有结果minute。可以看到:1、某头牛变成leader以后的energy是 总能量 - distance。 2、当leader > N || energy < 0这些情况都是非法的。3、distance == D这种情况是终止状态。设 f[ld][sp][e][dis] 表示当前leader是ld,以速度sp到达能量剩余为e,行走距离为dis的状态所用的最少时间。 然后记忆化搜索可破#include <iostream>#include <cstdio>#inclu 阅读全文
posted @ 2012-08-13 15:29 AC_Von 阅读(567) 评论(0) 推荐(0) 编辑
摘要:错过了。。。当练习做的。250pt 略500pt怎么开始就没敢写暴力呢。。。。看别人的思路,挺巧妙的。Orzclass ColorfulChocolates {public: int maximumSpread(string c, int m) { int l = c.length(), i, j, num, cnt; int s[3000]; int sum, ans = 0, res; REP(i, l) { num = 0; cnt = 0; for(j = i - ... 阅读全文
posted @ 2012-08-12 16:30 AC_Von 阅读(208) 评论(0) 推荐(0) 编辑
摘要:题意:N个点的一颗树。问最少添加多少条边可以让每个点都在一个(且仅一个)环中。不得不佩服,这题dp设计出来的人。。。偶是弱菜,只能膜拜了。这位大牛的解说,很详细:http://hi.baidu.com/19930705cxjff/blog/item/1df66e4a4ff3022e08f7ef5d.html 首先明确一点,题中的环至少需要3个顶点。因此,对于树中的每个顶点,有3种状态。f[x][0]表示以x为根的树,变成每个顶点恰好在一个环中的图,需要连的最少边数。f[x][1]表示以x为根的树,除了根x以外,其余顶点变成每个顶点恰好在一个环中的图,需要连的最少边数。f[x][2]表示以x为根 阅读全文
posted @ 2012-08-12 16:23 AC_Von 阅读(986) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示