基础DP
基础DP
River_____________
这个作者很懒,什么都没留下…
展开
-
历届试题 对局匹配 DP java
问题描述 小明喜欢在一个围棋网站上找别人在线对弈。这个网站上所有注册用户都有一个积分,代表他的围棋水平。 小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配在一起。如果两人分差小于或大于K,系统都不会将他们匹配。 现在小明知道这个网站总共有N名用户,以及他们的积分分别是A1, A2, ... AN。 小明想了解最多可能有多少名用户同时在线寻找对手,但是系统...原创 2019-03-10 17:44:26 · 305 阅读 · 0 评论 -
F - Eating Together POJ - 3670 (LIS)
裸的LIS(没学过。。 拿DP大力n2,直接超时 借此学一下LIS ———————————————————————————————————————————————————— DP数组: DP【i】代表长度为 i 的序列的结尾的 数字 思路有点贪心。 新的DP数组相当于一个贪心的序列。 从前往后扫描的过程中不断地把原序列的元素加入到DP数组里,对于每一个原序列的元素a【i】而言原创 2017-06-30 11:11:54 · 207 阅读 · 0 评论 -
HDU2870(和HDU1505 1506相同)
(偷懒原创 2017-06-04 15:26:16 · 253 阅读 · 0 评论 -
uva11464(递推)
枚举第一行的情况就能递推出下面的各个行的。 瞎退,细节挺多的,代码弱的容易wa细节(就是我 #include #include #include #include #include #include #include #include #include using namespace std; #define cir(a,b) memset(a,b,size原创 2017-06-28 21:46:31 · 206 阅读 · 0 评论 -
HDU2577
#include #include #include #include #include #include #include #include #include using namespace std; #define cir(a,b) memset(a,b,sizeof a) typedef long long LL; const int maxn = 100000+10;原创 2017-06-02 17:36:27 · 260 阅读 · 0 评论 -
HDU2845
#include #include #include #include using namespace std; int l,r; int s[10005][10005]; int dp1[200005],dp2[200005]; int main() { while(scanf("%d%d",&l,&r)!=EOF) { for(int i=2; i<l原创 2017-06-01 21:50:12 · 320 阅读 · 0 评论 -
HDU2159
#include #include #include #include using namespace std; int n,m,k,s; const int maxn = 10000+10; int dp[maxn]; int sum[maxn]; int w[maxn],v[maxn]; int main() { while(scanf("%d%d%d%d",&n,&m,&k,原创 2017-06-01 18:36:04 · 519 阅读 · 0 评论 -
HDU 2844(多重背包)
裸的多重背包模板,需要二进制优化才能不超时 0.0 #include #include #include #include #include using namespace std; //#define memset(a,b,sizeof a) cir(a,b) const int maxn = 100000+10; int v[maxn],w[maxn]; int n,m;原创 2017-05-31 21:25:39 · 200 阅读 · 0 评论 -
HDU2602(基础01背包)
最简单的01背包。 #include #include #include #include using namespace std; const int maxn = 1e3+5; int dp[maxn],w[maxn],v[maxn]; int m,n; int k; int main() { scanf("%d",&k); while(k--) {原创 2017-05-19 14:51:22 · 291 阅读 · 0 评论 -
UVALive - 3942(前缀树DP)
给出一个字符串和一些字符片段,求由这些字符片段组成这个字符串可以有多少种组的方法。 Sample Input abcd 4 a b cd ab Sample Output Case 1: 2 明显 对于字符串上的每个位置而言,如果用dp【i】代表从i开始的后缀最多有多少种组合方式的话,dp【i】 = sum(dp【i】 + l原创 2017-06-27 17:44:41 · 202 阅读 · 0 评论 -
期望DP入门(POJ 1190 ,POJ 2609)
通过这两道比较简单的题目算是入门一下期望DP。 期望DP是从后往前,概率DP是从前往后,二者还是有一定的相似性的。 当前的期望等于子期望加起来加上转移花费 POJ 1190 每次转移花费为1,通过虫洞没有花费。 对于每个位置如果是虫洞的起点的话就直接dp起点等于dp终点,如果不是那就是由当前点后面的6个点转移过来的。 #include #i原创 2017-07-18 17:00:10 · 636 阅读 · 1 评论 -
UVA - 12563 (DP维护多个特征)
求在歌曲的数目最多的情况下,花费的时间最大为多少。 单独维护最大消耗时间和最多的曲目都是普通的01背包,但是维护在曲目最多的情况下维护最大消耗时间,在更新的时候如果数目没法更新的话,在保证数目一样的情况下,更新一下最大时间消耗就可以了。 #include #include #include #include using namespace原创 2017-08-26 15:58:46 · 185 阅读 · 0 评论 -
【最长公共子序列(LCS)】
问题描述 给出两个字符串A,B求两个的字符串的最长公共子序列,求得的子序列可以不连续,只要保证子序列的元素相对的相对顺序和AB都保持一致就可以。 解决方案 DP[i][j]代表 A串从起点到i位置的字串 和 B串从起点到j位置的字串 的LCS DP递推式是显然的 当A[i] == B[j] 时 :DP[i][j] = DP[i-1][j-1] + 1 当A[i] != B[j...原创 2018-11-16 22:17:51 · 125 阅读 · 0 评论 -
Codeforces 808G(KMP+DP)
转移的时候要注意对于S[0--i]后缀的最长匹配 如果最长匹配为整个T串,那么就可以开始转移,转移时新出现的T可以从上一个完整的T的公共前缀的next转移加1过来,这就相当于用上一个T中的后缀作为当前T的前缀,不断求NEXT求出一个最大的转移,不断执行。 #include <bits/stdc++.h> using namespace std; const int maxn = 1...原创 2018-07-26 16:11:28 · 423 阅读 · 0 评论 -
UVA_11584(DP)
题意:给一个字符串,求最少能分成几个回文串。 dp[i] 代表前i+1个字符最少分成几个串。 每个新的结尾字符有两种选择: 1.加入一个串使这个新串变成回文串 2.自己成为一个新串 #include #include #include #include #include #include using namespace std; int dp[100000]原创 2017-10-12 16:28:08 · 170 阅读 · 0 评论 -
HDU 1160(记录路径的最长上升子序列)
那一个pre记录一下路径,递归输出就行了。 n2可以过 #include using namespace std; #define INF 0x3f3f3f3f const int maxn = 10000+10; struct Mouse { int speed,wight,pos; operator < (const Mouse &t) {原创 2017-10-04 14:33:13 · 263 阅读 · 0 评论 -
HDU - 1260(DP)
有k个人要买票,第i个人自己买花费时间alone[i],第i个人与相邻的人一起花费时间together[i],求所有人都买完花费的最少时间。 dp[i][0]代表前i个人买完并且第i个人是单独买的时候的最小花费时间, dp[i][1]代表前i个人买完并且第i个人是和他的前一个一起买的的状态下的最小花费时间。 #include using namespace std; cons原创 2017-10-04 10:54:53 · 166 阅读 · 0 评论 -
CodeForces - 869C(DP)
先求出任意两两之间的映射的种类数,然后求一下三种的乘积就可以了。 总想着内存是5000*5000*5000,没想到先求两两之间的,菜的一笔。 直接拿dp[i][j] 代表有i个红颜色小岛,j个蓝颜色小岛的情况下有多少种。 新增的小岛有两种情况:1.不和其他小岛相连 2.和另一种颜色的某个小岛相连 dp[i][j] = ( dp[i-1][j] + ( dp[i-1][j-1] * j原创 2017-10-07 18:15:19 · 416 阅读 · 0 评论 -
HDU1024
//dp[i][j] 是前j个组成i组的最大值 // //由 dp[i-1][j] + a[j] //和 dp[i-1][k] + a[j] k > 0 k < j 中的最大值转移而来 // //n 最大1000000 , 很可能会爆内存, //滚动优化一下, 但是时间还是n3的, //dp[i-1][k] + a[j] 的最大值就是 上一个循环中的最大值,直接保存可以砍掉一个n #inclu原创 2017-09-13 00:31:09 · 487 阅读 · 0 评论 -
最小回文串划分
转移方程 dp[i] = min(dp[j-1] + 1 , dp[i]) 1 #include #include #include #include #include #include using namespace std; int dp[100000]; char s[100000]; int T; bool judge(int from , int to) { whi原创 2017-08-29 20:13:37 · 440 阅读 · 0 评论 -
HDU1506
单调栈也可以做。 这里练DP就不用单调栈了。 #include #include #include using namespace std; const int maxn = 100000+10; typedef long long ll; ll s[maxn]; ll dp[maxn]; int l[maxn],r[maxn]; int n; int main() { whil原创 2017-05-18 22:42:08 · 684 阅读 · 0 评论 -
HDU1231(数据很水)
第三题: 直接从前往后扫描一遍,求出后以每个位置结束的最大的值。 状态方程:dp[i] = max( dp[i-1]+s[i],dp[i] ); 然后从后往前寻找起点就行了。 此题数据很水! 6 1 2 -1 -1 -1 -1 输出 2 2 2都能过。。(可能数据没考虑第一个数字的各种情况) 修正代码: #include #include #include原创 2017-05-18 17:24:26 · 261 阅读 · 0 评论 -
HDU1003(最大连续子序列)
和上一个思路一样,差别仅仅是一个输出值,一个输出位置 #include #include #include #include using namespace std; const int maxn = 1000000+10; int s[maxn]; int n; int dp[maxn]; int pd[maxn]; int T; int main() { cin >> T;原创 2017-05-18 18:00:53 · 294 阅读 · 0 评论 -
Stacking Boxes UVA - 103(矩形嵌套)
大意是有一些n维的物体,他的边也是n条,如果将一个物体的边按任意顺序排列,只要有一种排列满足一一对应小于另一物体的边,就可以将这个物体嵌套进去另一个物体中,文最多能连续嵌套几个物体。 和最长递增子序列差不多,只不过这里需要重新写一下比较函数 Some concepts转载 2017-03-13 14:08:50 · 251 阅读 · 0 评论 -
寒冰王座 HDU - 1248
完全背包问题,n元的钞票看做背包,小费是背包的最小剩余空间,也是最大的价值,两者看做相同。 int max(int a, int b) { return a > b ? a : b; } int main() { int t; int n; int arr[3] = {150, 200, 350}; int i, j; int dp[1000原创 2017-03-13 13:37:30 · 212 阅读 · 0 评论 -
Charm Bracelet POJ - 3624
Charm Bracelet POJ - 3624 Bessie has gone to the mall's jewelry store and spies a charm bracelet. Of course, she'd like to fill it with the best charms possible from the N (1 ≤ N ≤ 3,402) ava原创 2017-03-13 13:14:04 · 185 阅读 · 0 评论 -
Common Subsequence POJ - 1458(dp)
Common Subsequence POJ - 1458 A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = another sequence Z = is a subsequenc原创 2017-03-13 12:57:12 · 186 阅读 · 0 评论 -
Longest Ordered Subsequence POJ - 2533(最长上升子序列)
Longest Ordered Subsequence POJ - 2533 A numeric sequence of ai is ordered if a1 a2 aN. Let the subsequence of the given numeric sequence ( a1, a2, ..., aN) be any sequence ( ai1, ai2, ...,原创 2017-03-19 13:04:12 · 329 阅读 · 0 评论 -
正向01背包和数组保存简化背包
#include #include #include using namespace std; int dp[20][20]; int m,n; int w[20],v[20]; int rec(int i,int j) { if(dp[i][j]>=0) { return dp[i][j]; } int res; if(i==n)原创 2017-03-08 21:07:54 · 206 阅读 · 0 评论 -
Yogurt factory POJ - 2393
比较简单的dp:第n+1周的订单的最小花费是min(第一周做出来保存,第二周做出来保存。。。第n+1周直接制作) 由此可以得出dp[n+1]=min(dp[n]+s,dp[n+1])。 客户的订单的数量没什么用。 #include #include #include using namespace std; int c[10005],y[10005]; int main ()原创 2017-03-05 09:56:23 · 286 阅读 · 0 评论 -
Sumsets POJ - 2229
题意:给一个数,将其进行分解,只能分解为2的幂次,最多能分解多少种。 分析:对于奇数n,F(n)与F(n-1)只有一个1的差别,所以n的最大分解种一定和n-1相同。 对于偶数m,F(m)由两种类型的组合组成,一部分是不包含1的组合(不包含1时的种类就等于F(m/2)的种类数,因为此时的队列的所有元素都除以2的话就是F(m/2)的组合) 收获:向前寻找相关原创 2017-03-01 19:29:09 · 391 阅读 · 0 评论 -
Longest Ordered Subsequence POJ - 2533 (最长上升子序列)
Longest Ordered Subsequence POJ - 2533 A numeric sequence of ai is ordered if a1 a2 aN. Let the subsequence of the given numeric sequence ( a1, a2, ..., aN) be any sequence ( ai1, ai2, ..., a原创 2017-03-13 14:11:28 · 216 阅读 · 0 评论 -
HDU1505(记忆化查找)
本题和1506思路完全一样。只不过需要把图中的点转化为高度,以每行底来查找最大面积*3; 都是利用记忆化查找的思想来查找最左或者最右的边界,具体解释看代码。 #include #include #include #include #include #include #include #include #include using namespace std; #defi原创 2017-05-23 14:36:46 · 217 阅读 · 0 评论 -
HDU2602(01背包)
最基本的01背包,一个滚动优化就解决了、 #include #include #include #include using namespace std; const int maxn = 1e3+5; int dp[maxn],w[maxn],v[maxn]; int m,n; int k; int main() { scanf("%d",&k); while(k--)原创 2017-05-23 14:39:55 · 233 阅读 · 0 评论 -
HDU1864(01背包)
题意还是比较复杂的,限制比较多,需要先筛除不满足报销条件的发票: 1.出现 ABC之外的类不报销;2.一张发票内单个类超过600元不报销;3.发票的总金额超过1000不报销。 知道这三个条件之后筛除不满足的剩下的就是01背包了。 这里金额是double类,所以统一乘100,最后再除掉就好了(数据范围可以接受的情况下),把重量和价值看作一样,不过这样会很慢。 方程:dp[j] = max(原创 2017-05-18 12:55:14 · 414 阅读 · 0 评论 -
01背包空间优化
for (int i = 1; i <= n; i++) { for (int j = v; j >= 0; j--) { dp[j] = max(dp[j], dp[j - c[i]] + w[i]); } } 在关于二层循环的方向问题上我之前不是很清楚,主要解释一下这里。原创 2017-05-17 16:13:23 · 301 阅读 · 0 评论 -
HDU1203(01)
#include #include #include #include #include #include #include #include #include using namespace std; #define cir(a,b) memset(a,b,sizeof a) typedef long long LL; const int maxn = 100000+10;原创 2017-05-26 15:57:17 · 484 阅读 · 0 评论 -
HDU1176(二维动态规划)
没考虑到是二维的矩阵DP , 一开始想着按照最长不递减序列做的 , 不出意外的T 了。 需要矩阵优化才可以过。具体方法很简单,就是方向不好找罢了。 #include #include #include #include #include #include #include #include #include using namespace std; #defi原创 2017-05-24 19:43:36 · 353 阅读 · 0 评论 -
HDU2084(DP)
每次找相邻的点的中的max,计入dp中就可以了 #include #include #include #include #include #include #include #include #include using namespace std; #define cir(a,b) memset(a,b,sizeof a) typedef long long LL; con原创 2017-05-24 14:26:20 · 195 阅读 · 0 评论 -
HDU1069(DAG)
最简单的DAG了,只需要排个序,dp【i】 代表以第i个为结尾可以堆成的最大高度。 #include #include #include #include #include #include #include #include #include using namespace std; #define cir(a,b) memset(a,b,sizeof a) typedef原创 2017-05-24 09:28:21 · 231 阅读 · 0 评论