动态规划
FightingForFinal
这个作者很懒,什么都没留下…
展开
-
最长上升子序列O(n^2)
从序列 {A[1] , A[2] , A[3] …… A[n] } 中选出尽量多的数(不改变先后顺序)组成一个上升序列(严格递增序列) 如{1,6,2,3,7,5},可以选出上升子序列{1,2,3,5},也可以选出{1,6,7},但前者更长。这是动态规划的问题,设d[i]为以i结尾的最长上升序列的长度,则状态转移方程:d[ i ] = max{ 0 , d[ j ] | j#include<ios原创 2015-11-01 19:44:28 · 297 阅读 · 0 评论 -
hdu5763Another Meaning 2016 Multi-University Training Contest 4(kmp+dp)
首先用kmp找出所有模式串的位置放在id中(vector类型),然后做dp,dp方程为: 对于第i个位置,如果第j( j < i 中最大的 j )个位置满足 id[i]-id[j]>=son.size()(即模式串在主串中的这两个位置不重叠), 则d[i]=d[i-1]+d[j]; 如果这个j不存在则d[i]=d[i-1]+1。#include<bits/stdc++.h>using na原创 2016-07-28 20:34:05 · 271 阅读 · 0 评论 -
最短编辑距离
51nod 1183 编辑距离 题意:插入或删除或修改最少的字符,使两个字符串相同 设d[i][j]表示字符串a[1~i]和b[1~j]的最小编辑距离,则 注意边界。#include<bits/stdc++.h>using namespace std;const int maxn=1000;const int INF=0x3f3f3f3f;char a[maxn+5];char原创 2016-07-18 12:48:47 · 296 阅读 · 0 评论 -
poj1221 UNIMODAL PALINDROMIC DECOMPOSITIONS
题意很简单,给你一个正整数数n,将n拆分成一个正整数数字序列,要求数字序列和为n且是个回文并且左半部分的序列非降。问n拆分成这样的序列有几种方案?设d(n,k)表示n左右两边是k的时候的方案数,那么递推式: 表示当前这一种方案(n,k)加上方案(n-2i,i)的方案数,注意一下边界。本题其实就是一个递推式,由于用到了记忆化所以就写得跟dp一样了。。。。#include<cstdio>#inc原创 2016-07-25 20:30:54 · 561 阅读 · 0 评论 -
取若干个数求和等于k
51nod1268 和为K的组合 方法一:由于k最大取到20*1000000,所以用01背包可以解决,复杂度O(n * k)#include<bits/stdc++.h>using namespace std;int a[25];int n,k;int f[1000000+5];int main(){ ios::sync_with_stdio(false); cin>>n>原创 2016-07-02 22:48:24 · 1018 阅读 · 0 评论 -
树的重心
对于一个有n个结点的无根树,找一个点作为根,使得最大子树的结点数最小,换句话说,删除这个点后最大连通块的结点数最小。 任选一个点作为根,设d(i)表示以i为根的子树的结点个数,那么: 只需要一次dfs,连记忆化都不需要,因为没有重复计算。现在重点来了: 删除结点i之后,最大连通块有多少个结点呢? 结点i的子树中最大的有max{d(j)}个结点,i的“上方子树”中有n-d(i)个结点!po原创 2016-05-06 15:24:44 · 674 阅读 · 0 评论 -
树的最大独立集
任选一个结点当根,用d(i)表示以i为根结点的子树的最大独立集大小,结点i只有两种决策:选或不选。如果选了i,则i的儿子都不能选;如果不选i,那么问题转化成求i的所有儿子的d值再相加。状态转移方程: 其中s(i)和gs(i)分别是i的儿子集合与孙子集合。 实现方法:当计算出一个d(i)后,用它去更新i的父结点和祖父结点,所以每次只要记录父结点即可 poj2342 Anniversary p原创 2016-05-06 15:08:01 · 943 阅读 · 0 评论 -
树上最长路
树上存在最远的两个点(b,e),那么距离其他点x最远的点一定是b或者e。 因此可以任选一个点做dfs找到最远的点b,再从b做一次dfs找到e,最远距离便算出来了。 如果要求任意点x的最远距离,那么maxdis=max( dis(x,b) , dis(x,e) ); 定义d(i)表示点i到根结点的最远距离,那么把b和e分别做根结点进行dfsComputer 题意就是要求任意点的最远距离#inc原创 2016-05-12 18:39:29 · 737 阅读 · 0 评论 -
插入最少字符使原串变成回文串
51nod1092 回文字符串 解法一: 将原串逆序之后求一下LCS即可:#include<bits/stdc++.h>using namespace std;const int maxn=1000;char a[maxn+10];char b[maxn+10];int sum[maxn+10][maxn+10];int main(){ scanf("%s",a+1);原创 2016-05-24 18:00:27 · 4597 阅读 · 0 评论 -
最长公共子序列(LCS)
#include<cstdio>#include<cstring>#include<iostream>#include<stack>using namespace std;char a[1000+5],b[1000+5];int sum[1000+5][1000+5];void work(){ memset(sum,0,sizeof(sum)); int la=strlen原创 2016-02-28 19:36:17 · 281 阅读 · 0 评论 -
最长非降子序列O(nlogn)
在最长上升序列O(nlogn)中当计算出的两个状态a和b满足A[a] < A[b]且d[a] = d[b]时,取a是最优的,但在非降这个要求中我们要保留的是b,因为一样的元素取的是最后一个,比如{1,2,2}中会取到第二个2,所以g[i]表示d值为i的最最大状态编号(如果存在),因此将lower_bound(返回第一个等于value的值的位置)更换成upper_bound(返回最后一个等于value原创 2015-11-01 20:34:29 · 802 阅读 · 0 评论 -
最长上升子序列O(nlogn)
假设已经计算出的两个状态a和b满足A[a] < A[b]且d[a] = d[b],则对于后续所有的状态i(即i > a且i > b)来说,a并不会比b差——如果b满足A[b] < A[i]的条件,a肯定也满足,且二者的d值相同;但反过来却不一定了,a满足A[a] < A[i]的条件时,b却不一定满足。换句话说,如果我们只保留a,一定不会丢失最优解。 这样,对于相同的d值,只需保留A最小的一个。设g原创 2015-11-01 20:11:46 · 342 阅读 · 0 评论 -
poj1065 Wooden Sticks(没有交集元素的lis的条数)
题意:给你n个棍子,棍子有两个属性l和w,开启机器加工这些棍子,如果满足l1<=l2且w1<=w2,加工完棍子1之后便可以加工棍子2,否则要再次启动机器,问最少要启动几次? 题意等价于:给出若干个偏序,求出这样一个集合的大小,该集合中任意两个偏序都不可比较。分析:如果将棍子按照其中一个属性升序(属性值相同就按另一属性值升序),那么就是求另一个属性的lis链最少条数,要求各条lis链之间不包含相同下原创 2016-07-30 18:32:52 · 405 阅读 · 0 评论