DP
文章平均质量分 54
RuHua27
这个作者很懒,什么都没留下…
展开
-
HDOJ 1203 I NEED A OFFER!(简单背包)
求得不到 offer 的最小概率即可。 显然可以转化为简单背包。 #include #include #include using namespace std; const int maxn = 10100, maxv = 10100; int n, m; int c[maxn]; double p[maxn]; double dp[maxv]; int main() { w原创 2013-12-25 13:33:18 · 475 阅读 · 0 评论 -
HDOJ 1208 Pascal's Travels(水DP)
水DP。。。 #include #include #include using namespace std; typedef long long LL; const int maxn = 40, inf = 0x3f3f3f3f; LL mat[maxn][maxn], dpa[maxn][maxn]; int n; LL dp(int i, int j) { if(~dpa[i原创 2013-12-27 20:00:36 · 501 阅读 · 0 评论 -
HDOJ 1114 Piggy-Bank(完全背包,水)
水多重背包,求的是 min 而不是常见的 max dp[i][v] = min(dp[i][v], dp[i][v-c[i]] + w[i]) #include #include #include using namespace std; const int maxn = 11000, inf = 0x3f3f3f3f; int dp[maxn], p[maxn], w[maxn];原创 2013-12-23 10:16:45 · 487 阅读 · 0 评论 -
HDOJ 1080 Human Gene Functions(DP)
方程不是很难的 DP,刚开始看错题意,以为是在较短串里加空格使得匹配度最好,后来看了 discuss 才发现长串也可以加空格。。。 dp(i,j) 表示以串1的第 i 位开始的串和以串2的第 j 位开始的串的最大匹配值。 dp(i,j) = max( dp(i+1,j)+f(s1[i], '-'), dp(i,j+1)+f('-', s2[j]), dp(i+1,j+1)+f(s1[i], s原创 2014-02-16 11:11:31 · 383 阅读 · 0 评论 -
HDOJ 3535 AreYouBusy (分情况的分组背包)
题意:n 组,每组有 m 个物品,每一组的属性为 0 或 1 或 2 。 0 代表该组中至少取一个,1 代表至多取一个,2 代表没有限制。 cost[i][j] hap[i][j] 存第 i 组第 j 个物品的花费和价值。 令 dp[i][j] 表示前 i 组,花费不超过 j 时的最大价值。 dp[i][j] 转移: a: dp[i-1][j-cost[i][j]] + hap[原创 2014-03-04 19:31:10 · 518 阅读 · 0 评论 -
HDOJ 4049 Tourism Planning(状态压缩DP)
题意:N (N≤10)个人按照已经定好的顺序参观M(M≤10)个景点,每个景点都有花费 c,每个人对每个景点有一个喜欢的程度值 a,每两个人之间有一个喜欢的程度值 b,如果他们一起参观某个景点会产生。每个人都可以中途推出旅行,求使得 a + b - c 最大的方案的值。 dp[i][s]代表参观到第 i 个景点,剩下的人集合为 s 所能得到的最大值。 dp[i][s] = max(dp[i原创 2014-03-05 21:08:03 · 422 阅读 · 0 评论 -
HDOJ 2089 不要62 (数位DP)
第一道数位DP的题目.(后来发现这题可以不用DP水过。。。) 还是花了挺长时间的,原理不难懂,但是细节总是有问题。 题意:给定一个区间,求该区间没有 "4" 或在一起的 "62" 的数的个数。 dp[i][j] 表示 i 位数,j 开头满足条件的数的个数。 则 dp[i][j] = sigma(k = 0 to 9) (dp[i-1][k]) (j != 4, !(j == 6 &原创 2014-03-11 21:03:38 · 357 阅读 · 0 评论 -
HDOJ 4433 Locker (数位DP)
题意,给一个密码锁的初始状态和目标状态,每次可以将连续的 1 - 3 位向上或者向下挪一位,问达到目标状态最少需要多少次。 参考了网上的题解。。。 dp[i][x][y] 表示 在第 i-1 位是 x 第 i 位是 y 的情况下,把前 i 位弄好需要的步数。 想要转移的话,很有可能会把状态定义为“前 i 位 blablabla”。 于是,从后往前推,容易证明,想把第 i 位弄对,要么只正转原创 2014-03-11 21:15:44 · 419 阅读 · 0 评论 -
HDOJ 1011 Starship Troopers(树形DP)
第一道树形DP。。 参考了网上的题解,了解了树形DP与DFS一起用的思路。 题意:bugs 组成了一棵树,你带着士兵从根结点进入,干掉某个结点的 bug 可以得到一定的 brain 。显然每个结点到根结点都有唯一的路径,如果你想干掉某个结点,那么该路径的结点都必须被干掉,给你 m 个士兵,求得到 brain 最多的方案。 dp[i][j] 表示处理到结点 i 剩余 j 个士兵的最优解,本题答原创 2014-03-14 12:34:06 · 800 阅读 · 0 评论 -
HDOJ 1561 The more, The Better(树形DP)
在树上做背包。 学到一点:如果想要处理的是树,但是题目中给的是森林的话,可以加一个总的根结点。 A 掉 1011 之后这题就比较顺利的 1A 了。 代码: #include #include #include using namespace std; const int maxn = 220, inf = 0x3f3f3f3f; int n, m; int fr[maxn * 2]原创 2014-03-14 12:37:45 · 436 阅读 · 0 评论 -
HDOJ 4815 Little Tiger vs. Deep Monkey(简单DP)
2013长春现场赛的题,简单DP。 #include #include #include using namespace std; const int maxn = 50, maxs = 50000; int s[maxn]; double dp[maxn][maxs]; int main() { int t; for(scanf("%d", &t); t--;)原创 2014-03-16 12:23:23 · 376 阅读 · 0 评论 -
HDOJ 1160 FatMouse's Speed(LIS)
#include #include #include #include using namespace std; vector a, b; const int maxn = 1100; int dp[maxn], pre[maxn], od[maxn]; void printAns(int cur) { if(cur != -1) { printAns(pre[原创 2013-12-23 11:20:43 · 561 阅读 · 0 评论 -
HDOJ 2602 Bone Collector(水,简单背包)
简单背包,题意有问题,数据是先 volume 后 value,描述却说先 value 后 volume 。 #include #include #include using namespace std; const int maxn = 1100; int dp[maxn], c[maxn], v[maxn]; int main() { int t; for(cin原创 2013-12-19 10:22:53 · 432 阅读 · 0 评论 -
HDOJ 1087 Super Jumping! Jumping! Jumping! (水,LIS)
很裸的 LIS 。 #include #include #include using namespace std; int main() { int a[1100], dp[1100]; for(int n; ~scanf("%d", &n) && n;) { int ans = 0; for(int i = 0; i < n; i++)原创 2013-12-19 12:52:16 · 328 阅读 · 0 评论 -
HDOJ 1003 Max Sum
DP水题。dp[i] 表示以 i 结尾的最大子序列。 方程:dp[i] = max(dp[i-1] + a[i], a[i]) 选择最大的 dp[i] 即可。 需要注意一下要求输出 "the first one",即 dp 值相等时优先考虑 lt 值较小的。 总结:dp[i] 不一定表示最终答案,可以先得到所有点的 dp 值,再通过枚举得到答案。 #include原创 2013-12-11 10:53:58 · 358 阅读 · 0 评论 -
HDOJ 1176 免费馅饼
方程比较简单的DP。 dp[t][x] = cnt[t][x] + max(dp[t+1][x], dp[t+1][x+1], dp[t+1][x-1]) 总结:开始写成记忆化搜索爆栈了,然后发现 t 时刻完全可以由 t+1 推出,所以改成用循环来推就 AC 了。 #include #include using namespace std; const int maxn = 10200原创 2013-12-11 16:04:51 · 455 阅读 · 0 评论 -
HDOJ 1059 Dividing (多重背包例题)
问题很容易转化为多重背包问题。刚学背包(。。。)用它练练手。 多重背包的特殊性在于物品可以取多次。 首先利用二进制表示数的特点,可以把每个物品的个数由 n 降为 log n 。 然后循环的时候第二层循环顺序和普通背包刚好相反,这是因为普通背包 dp[i][v1] 只可能由 dp[i-1][v2] 推得,而多重背包由于可以取多次,依然可以由dp[i][v2] 推得。 方程:dp[i][v]原创 2013-12-12 13:04:26 · 1183 阅读 · 0 评论 -
HDOJ 1069 Monkey and Banana(LIS)
题意,给出 n 种长方体的 a, b, c,每种都有无限多个,把它们盖成一个塔,要求相邻的下层长和宽都要严格大于上层。 刚开始想了个DAG上动态规划的做法(感觉直观上第一反应就是这种做法啊。。。)但是貌似有点小问题,虽然样例能过,但是会 STACK_OVERFLOW ,然后以为是记忆化搜索的问题,改成非递归的,直接 TLE 了。。。 于是上网找了正解。。。 显然每个长方体都有三种不同的形态,原创 2013-12-13 11:51:52 · 476 阅读 · 0 评论 -
HDOJ 1159 Common Subsequence(水DP,LCS)
DP 水题。 方程 dp[i][j] = (s1[i] == s2[j]) ? dp[i-1][j-1] + 1 : max(dp[i-1][jj], dp[i][j-1]) 初始化 WA 了一记。。。 具体见代码注释 #include #include #include #include using namespace std; const int maxn = 1000; i原创 2013-12-16 10:26:36 · 468 阅读 · 0 评论 -
HDOJ 1723 Distribute Message(超水DP)
期末复习累了,水水~ #include #include using namespace std; int dp[35]; int main() { int n, m; while(~scanf("%d%d", &n, &m) && (n || m)) { memset(dp, 0, sizeof(dp)); dp[0] = 1;原创 2013-12-30 15:45:05 · 372 阅读 · 0 评论 -
HDOJ 1074 Doing Homework (状态压缩DP)
第一次写状态压缩DP。。参考了 kuangbin 大神的代码。。学习了 感觉状压用位运算的技巧比较多,而且因为数据一般都是 n dp[i] = min(dp[j] + penalty), j 是 i 只差一个元素的子状态 初始化 dp[0] = 0, dp[i] = inf (i ≠ 0) 可以对所有状态进行一次循环,并更新由该状态加一个 “1” 得到的新状态。。 由于要输出答案顺序,原创 2013-12-16 09:37:33 · 437 阅读 · 0 评论 -
HDOJ 1331/HDOJ 1579 Function Run Fun(水递推)
水递推。。。 #include using namespace std; const int maxn = 21; int dp[maxn][maxn][maxn]; int main() { for(int i = 0; i < maxn; i++) for(int j = 0; j < maxn; j++) dp[0][i][j] = d原创 2013-12-27 20:02:03 · 602 阅读 · 0 评论 -
HDOJ 1025 Constructing Roads In JGShining's Kingdom(LIS O(nlogn) )
一看数据量就知道要 O(nlogn) 的 LIS 于是上网学了下。。 DP方程仍然是 dp[i] = max(dp[j]+1) (a[j] 不过这次用 f[i] 表示所有长度为 i 的上升子序列中结尾最早的那个子序列的结尾。(有点绕嘴。。) 这样就免去了求 max 的过程。 维护 f 数组,每当读入一个 a[i] 时,如果它比 f 中最后一个元素还大,则将 f 数组的长度增加1,并把原创 2013-12-16 13:59:21 · 442 阅读 · 0 评论 -
HDOJ 1078 FatMouse and Cheese(记忆化搜索)
首先是英语理解错,导致题意弄得有点复杂 runs either horizontally or vertically to another location 这句的意思是横着跑或竖着跑,但并不意味着在一次到下一个点的运动中可以既横着有竖着跑,即每跑一次,路径是不拐弯的。。 这样的话就比较简单了。。 dp[i][j] = a[i][j] + max(dp[i1][j1]) ,点(i,原创 2013-12-18 11:04:44 · 647 阅读 · 0 评论 -
HDOJ 1257 最少拦截系统(LIS O(nlogn) )
刚开始无从下手,然后突然想到可以归为 LIS 问题。 对于所给序列的 LIS ,设其长度为 len,显然这 len 个导弹至少各自需要一个系统,即 ans >= len 对于剩下的某个导弹 i ,假设其处于 LIS 中 f[a] 和 f[a+1] 之间,显然不可能 f[a] 若 f[i] 话说感觉明明应该是最长上升子序列,网上好多都说是最长非降子序列。。。 #include #in原创 2013-12-19 12:03:12 · 583 阅读 · 0 评论 -
ZOJ3735 Josephina and RPG(简单DP)
RT。 #include #include #include using namespace std; const int maxm = 120, maxn = 1e4; int n; double tab[maxm][maxm]; double dp[maxm][maxn]; int a[maxn]; int main() { int m, n; while (~sc原创 2014-07-31 19:39:50 · 472 阅读 · 0 评论