【动态规划】【子序列模板】
来源:互联网 发布:淘宝人生全文免费阅读 编辑:程序博客网 时间:2024/05/17 23:56
ACM模板
【最长上升子序列】
输出长度
O(n*n)
while(scanf("%s%s",s1+1,s2+1)!=EOF) { l1 = strlen(s1+1); l2 = strlen(s2+1); for(i = 0; i <= l1;i ++) f[i][0] = 0; for(i = 0; i <= l2; i ++) f[0][i] = 0; for(i = 1; i <= l1; i ++) { for(j = 1; j <= l2; j ++) { if(s1[i] == s2[j])//字符相等时,上一个状态长度加1 f[i][j] = f[i-1][j-1] + 1; else {//字符不等时,取最大的字符序列公共长度 if(f[i-1][j] > f[i][j-1]) f[i][j] = f[i-1][j]; else f[i][j] = f[i][j-1]; } } } printf("%d\n",f[l1][l2]); }
O(nlogn)
int find(int flag,int *end,int low,int high){//二分法查找end中最小的小于数flag的下标 int mid; while(low < high) { mid = (low+high)>>1; if(flag > end[mid]) low = mid + 1; else high = mid; } return low;}int main(){//end数组存储的是子序列长度为i的最小尾数 end[1] = num[1],len = 1;//len记录子序列最长长度 for(i = 2; i <= n; i ++) { if(num[i] > end[len])//如果求非递减的序列则加上等号 ans = ++len; else ans = find(num[i],end,1,len+1); end[ans] = num[i]; } printf("%d\n",len);}
回溯输出最长上升子序列 O(n*n)
void LCS(char *x,char *y,int n,int m,int a[][N+10],int b[][N+10] ){//找到最长公共子序列 for(i = 0; i <= n; i ++) a[i][0] = 0; for(j = 0; j <= m; j ++) a[0][j] = 0; for( i = 1; i <= n; i ++) for( j = 1; j <= m; j ++) { if(x[i-1] == y[j-1]) {//下标从0开始,故为i-1,j-1。 a[i][j] = a[i-1][j-1]+1; b[i][j] = 1; //字符相等标记为1 } else { if( a[i-1][j] > a[i][j-1]) { a[i][j] = a[i-1][j] ; b[i][j] = 0;//字符串1大标记为0 } else { a[i][j] = a[i][j-1] ; b[i][j] = -1;//字符串2大标记为1 } } } return;}void PrintLcs(char *s,int n,int m,int b[][N+10]){//回溯输出子序列 if( 0 == n|| 0 == m) return; else if( b[n][m] == 1) { PrintLcs(s,n-1,m-1,b); printf("%c",s[n-1]); } else if( b[n][m] == 0) PrintLcs(s,n-1,m,b); else if(b[n][m] == -1) PrintLcs(s,n,m-1,b);}int main(){ LCS(str1,str2,l1,l2,a,b); PrintLcs(str1,l1,l2,b); printf("\n"); return 0;}
【最大上升子段和】
/*max_len[N]存1~n各阶段的最大上升子段和*/ max_len[1] = num[1];//数组开始的最大上升子段和是第一个元素 max = num[1];//最大上升子段和初始化 for( i = 1; i <= n; i ++) { num_len = 0;//记录i左边的最大上升子段和 for(j = 1; j < i; j ++)//找到i左边的最大上升子段和 { if(num[i] > num[j]) { if(num_len < max_len[j]) num_len = max_len[j]; }//if } //for max_len[i] = num_len + num[i]; //i左边最大上升子段和加上自身的值 if(max_len[i] > max) max = max_len[i]; }//for printf("%d\n",max); //输出最大和
【连续最大子段和之输出最大子段和,起点,终点】
时间复杂度为O(n),舍弃数组存储的方法原因有:1:易粗心错估数据范围,2:降低时间复杂度
#include<stdio.h> int max_start,max_end;//最终的起始点和最终的终点 int now_start; //当前起始点 int now_sum; //当前的和 int max;//最大子段和 int num; //读入当前值 int main() { int n,i; while(scanf("%d",&n)!=EOF) { for(i = 1; i <= n; i ++) { scanf("%d",&num); if( i == 1) //如果是第一个值,初始化数据 { now_sum = max = num; now_start = max_end = i; } else { if( now_sum >= 0) now_sum += num; else { now_sum = num; now_start = i; //记录当前起始点 } } if( now_sum >= max) //更新最大值 { max = now_sum; max_start = now_start; //更新起始点 max_end = i; //更新终止点 } } printf("%d %d %d\n",max,max_start,max_end); //输出最大子段和,起始点,终止点 } return 0; }
阅读全文
0 0
- 【动态规划】【子序列模板】
- 动态规划--子序列
- 动态规划----最长子序列
- 【最长子序列 动态规划】
- 动态规划----最长子序列
- 【动态规划】最大子序列
- #动态规划# 子序列个数
- 动态规划-----子序列个数
- 动态规划-公共子序列
- 上升子序列(动态规划
- 动态规划-公共子序列
- 动态规划:公共子序列
- 动态规划 公共子序列
- 最长子序列--动态规划
- (动态规划)最长回文子序列、回文子序列个数
- (动态规划)最长回文子序列、回文子序列个数
- 最长递增子序列(动态规划)
- 动态规划--最长不降子序列
- 事件绑定和普通事件的区别
- 计算机网络--传输层
- linux上的一些简单的vim配置
- JVM——Java中的线程安全
- URAL1004 Sightseeing Trip(Folyd求最小环,打印路径)
- 【动态规划】【子序列模板】
- 在进行npm安装时发现node_modules不知道跑哪去了
- JS中navigator对象详解
- git 常用命令
- 动态代理
- Hdu 1241 Oil Deposits DFS算法
- 水平居中/按钮点击变色
- 简单基础树状数组求逆序数 POJ2299
- js实现点击按钮复制文本框中的内容