博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LIS && LCS && LCIS && LPS && MCS模板
阅读量:5012 次
发布时间:2019-06-12

本文共 5143 字,大约阅读时间需要 17 分钟。

1. LIS (Longest Increasing Subsequence)

O (n^2):

/*	LIS(Longest Increasing Subsequence)	最长上升子序列 O (n ^ 2)	状态转移方程:dp[i] = max (dp[j]) + 1 (a[j] < a[i],1 <= j < i)	附带有print输出路径函数*/void LIS(void)	{	int ret = 0, last = 0;	for (int i=1; i<=n; ++i)	{		dp[i] = 1;	fa[i] = -1;		for (int j=1; j

 

O (nlogn):

/*	LIS 二分查找优化, O(nlogn)	设当前最长递增子序列为len,考虑元素a[i]; 若d[len]
res; int i; for (i=pos[len]; ~fa[i]; i=fa[i]) res.push_back (a[i]); res.push_back (a[i]); for (int i=res.size ()-1; i>=0; --i) printf ("%d%c", res[i], i == 0 ? '\n' : ' ');}

 

 

2. LCS (Longest Common Subsequence)

/*    LCS(Longest Common Subsequence):        状态转移方程:dp[i][j] = dp[i-1][j-1] + 1; (s[i-1] == t[i-1])                    dp[i][j] = max (dp[i][j-1], dp[i-1][j]);(s[i-1] != t[i-1])        可滚动数组优化。附带有print输出路径函数。*/void LCS(void)  {    memset (dp, 0, sizeof (dp));    memset (fa, 0, sizeof (fa));    for (int i=0; i<=lens; ++i)    fa[i][0] = -1;    for (int i=0; i<=lent; ++i)    fa[0][i] = 1;    for (int i=1; i<=lens; ++i) {        for (int j=1; j<=lent; ++j) {            if (s[i-1] == t[j-1])   {                dp[i][j] = dp[i-1][j-1] + 1;                fa[i][j] = 0;            }            else if (dp[i-1][j] >= dp[i][j-1])  {                dp[i][j] = dp[i-1][j];                fa[i][j] = -1;            }            else    {                dp[i][j] = dp[i][j-1];                fa[i][j] = 1;            }        }    }    printf ("%d\n", dp[lens][lent]);    print (lens, lent); puts ("");}void print(int x, int y)    {    if (!x && !y)   return ;    if (fa[x][y] == 0)  {        print (x-1, y-1);    printf ("%c", s[x-1]);    }    else if (fa[x][y] == -1)    {        print (x-1, y);    printf ("%c", s[x-1]);    }    else    {        print (x, y-1);    printf ("%c", t[y-1]);    }}

 

 

3. LCIS (Longest Common Increasing Subsequence)

/*	LCIS(Longest Common Increasing Subsequence) 最长公共上升子序列	状态转移方程:a[i] != b[j]: dp[i][j] = dp[i-1][j]; 				  a[i] == b[j]: dp[j]=max(dp[j],dp[k]); (1<=k
b[j] && dp[i][j] > dp[i][k]) k = j; //找到最优的k if (ret < dp[i][j]) { ret = dp[i][j]; //更新所有dp中的最大值 sx = i, sy = j; } } } printf ("%d\n", ret); fir = true; print (sx, sy, -1); puts ("");}void print(int x, int y, int last) { //bool fir; if (x == 0 || y == 0) return ; print (fx[x][y], fy[x][y], y); if (y != last) { if (fir) printf ("%d", b[y]), fir = false; else printf (" %d", b[y]); }}

 

 

4. LPS (Longest Palidromic Subsequence)

/*    LCS的思想,dp[i][j]表示i到j的最长回文串长度,状态转移方程:        1. dp[j][j+i-1] = dp[j+1][j+i-2] + 2;   (str[j] == str[j+i-1])        2. dp[j][j+i-1] = max (dp[j+1][j+i-1], dp[j][j+i-2]);   (str[j] != str[j+i-1])    ans[1][len]是string类型,记录LPS字符*/void LPS(void)  {    int len = strlen (str + 1);    memset (dp, 0, sizeof (dp));    for (int i=1; i<=len; ++i)  dp[i][i] = 1;    for (int i=1; i<=len; ++i)  ans[i][i] = str[i];    for (int i=2; i<=len; ++i)   {              //区间长度        for (int j=1; j+i-1<=len; ++j)  {       //[j, j+i-1]            if (str[j] == str[j+i-1])   {                if (i == 2) {                    dp[j][j+i-1] = 2;                    ans[j][j+i-1] = ans[j][j] + ans[j+i-1][j+i-1];  continue;                }                dp[j][j+i-1] = dp[j+1][j+i-2] + 2;                ans[j][j+i-1] = str[j] + ans[j+1][j+i-2] + str[j+i-1];            }            else if (dp[j+1][j+i-1] > dp[j][j+i-2]) {                dp[j][j+i-1] = dp[j+1][j+i-1];                ans[j][j+i-1] = ans[j+1][j+i-1];            }            else if (dp[j][j+i-2] > dp[j+1][j+i-1]) {                dp[j][j+i-1] = dp[j][j+i-2];                ans[j][j+i-1] = ans[j][j+i-2];            }            else    {                dp[j][j+i-1] = dp[j+1][j+i-1];                ans[j][j+i-1] = min (ans[j+1][j+i-1], ans[j][j+i-2]);            }        }    }    int mlen = dp[1][len];    for (int i=0; i

 

5. MCS (Maximum Continuous Subsequence)

O (n):

/*	MCS (Maximum Continuous Subsequence) 最大子序列和 O (n)	1. DP	2. 前缀	若有多个答案输出第一个,均给出区间端点*/void MCS(int n)	{	int l = 0, ll = 0, rr = 0;	int sum = -INF, mx = -INF;	for (int i=1; i<=n; ++i)	{		if (sum + a[i] < a[i])	{			sum = a[i];	l = i;		}		else	sum += a[i];		if (sum > mx)	{			mx = sum;	ll = l, rr = i;		}	}	printf ("%d %d %d\n", mx, ll, rr);}

 

O (n) another:

//O (n) //anothervoid MCS(int n)	{	int l = 0, ll = 0, rr = 0;	int sum = 0, mx = -INF, mn = 0;	for (int i=1; i<=n; ++i)	{		sum += a[i];		if (sum - mn > mx)	{			mx = sum - mn;	ll = l;	rr = i;		}		if (sum < mn)	{			mn = sum;	l = i;		}	}	printf ("%d %d %d\n", mx, ll + 1, rr);}

 

O (nlogn):

//O (nlogn)     //输出端点困难int MCS(int *a, int l, int r)   {    if (l == r) {        if (a[l] > 0)    return a[l];        else    return 0;    }    int mid = (l + r) >> 1;    int lmax = MCS (a, l, mid);    int rmax = MCS (a, mid + 1, r);         int lbmax = 0, lbsum = 0;    for (int i=mid; i>=left; --i)   {  //之前写错了,应该是连续的        lbsum += a[i];        if (lbmax < lbsum)   lbmax = lbsum;    }    int rbmax = 0, rbsum = 0;    for (int i=mid+1; i<=r; ++i) {        rbsum += a[i];        if (rbmax < rbsum)   rbmax = rbsum;    }     return max (lbmax + rbmax, max (lmax, rmax));}

 

  

 

  

转载于:https://www.cnblogs.com/Running-Time/p/4778309.html

你可能感兴趣的文章
如何检测 51单片机IO口的下降沿
查看>>
扫描识别控件Dynamic .NET TWAIN使用教程:如何将事件添加到应用程序中
查看>>
创建和修改主键 (SQL)
查看>>
2018-2019 ICPC, NEERC, Southern Subregional Contest(训练记录)
查看>>
20145233 《信息安全系统设计基础》第7周学习总结
查看>>
linux设备驱动程序第3版学习笔记(例程2--hellop.c)
查看>>
玩转storm
查看>>
第10章 使用Apache服务部署静态网站
查看>>
关于给予webApp框架的开发工具
查看>>
c语言编写的生成泊松分布随机数
查看>>
Maven入门笔记
查看>>
iOS webView的常见属性和方法
查看>>
理解position:relative
查看>>
Codeforces Round #344 (Div. 2) Messager KMP的应用
查看>>
20145308刘昊阳 《Java程序设计》第4周学习总结
查看>>
js倒计时
查看>>
EasyUI datagrid 格式 二
查看>>
Android虹软人脸识别sdk使用工具类
查看>>
UI:基础
查看>>
浅谈 @RequestParam 和@PathVariable
查看>>