经典规划

经典规划

1.最大连续子序列和

给定一个数字序列 A 1 , A 2 , . . . , A n A_1,A_2,...,A_n A1,A2,...,An,求 i , j ( i ≤ j ≤ n ) , i,j(i\le j\le n) , i,j(ijn),使得 A i + . . . + A j A_i+...+A_j Ai+...+Aj最大,输出这个最大和
步骤1:令状态 d p [ i ] dp[i] dp[i]表示以 A [ i ] A[i] A[i]作为作为末尾的连续序列最大和,求解 d p [ i ] dp[i] dp[i]数组
步骤2:考虑两种情况
1 ◯ \text{\textcircled 1} 1 该序列只有一个元素, d p [ 0 ] = A [ 0 ] ; dp[0] = A[0]; dp[0]=A[0];
2 ◯ \text{\textcircled 2} 2该序列有多个元素, d p [ i ] = m a x { A [ i ] , d p [ i − 1 ] + A [ i ] } dp[i]=max\{ A[i],dp[i-1]+A[i]\} dp[i]=max{A[i],dp[i1]+A[i]} ( 状 态 转 移 方 程 ) (状态转移方程) ()

2.最长不下降子序列(LIS)

在一个数字序列中,找到一个最长的子序列(可以不连续),使得这个子序列是不下降的
步骤1:令状态 d p [ i ] dp[i] dp[i]表示以 A [ i ] A[i] A[i]作为作为末尾的 L I S LIS LIS长度
步骤2:对于 A [ i ] A[i] A[i]有两种情况
1 ◯ \text{\textcircled 1} 1 A [ i ] ≥ A [ j ]   ( j < i )   且   d p [ j ] + 1 > d p [ i ] ,   d p [ i ] = d p [ j ] + 1 ; A[i]\ge A[j]\ (j< i)\ 且\ dp[j]+1>dp[i],\ dp[i] = dp[j]+1; A[i]A[j] (j<i)  dp[j]+1>dp[i], dp[i]=dp[j]+1;
2 ◯ \text{\textcircled 2} 2如果 A [ i ] A[i] A[i]之前的元素都比 A [ i ] A[i] A[i]大,则只能自己形成一条链,且长度为1;
最后得出状态转移方程: d p [ i ] = m a x { 1 , d p [ j ] + 1 }                                ( j = 1 , 2 , ⋯   , i − 1 & & A [ j ] < A [ i ] ) dp[i] = max\{1,dp[j]+1\}\\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (j=1,2,\dotsb,i-1 \&\& A[j]<A[i]) dp[i]=max{1,dp[j]+1}                              (j=1,2,,i1&&A[j]<A[i])

3.最长公共子序列(LCS)

给定两个字符串 A , B A,B AB,求一个字符串,使得这个字符串是 A 和 B A和B AB的最长公共部分(子序列可以不连续)
例如 sadstory 和 adminsorry 的最长公共子序列为 adsory
步骤1:令状态 d p [ i ] [ j ] dp[i][j] dp[i][j]表示字符串 A A A i i i号位和字符串 B B B j j j号位之前的 L C S LCS LCS长度(下标从1开始)
步骤2: 两种决策
1 ◯ \text{\textcircled 1} 1 A [ i ] = = B [ j ] A[i]==B[j] A[i]==B[j],则 d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] + 1 dp[i][j]=dp[i-1][j-1]+1 dp[i][j]=dp[i1][j1]+1
2 ◯ \text{\textcircled 2} 2 A [ i ] ! = B [ j ] A[i]!=B[j] A[i]!=B[j] L C S LCS LCS无法延长,则继承 d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] dp[i-1][j],dp[i][j-1] dp[i1][j],dp[i][j1]中的最大值
由此可以得到状态转移方程:
d p [ i ] [ j ] = { d p [ i − 1 ] [ j − 1 ] + 1 ,   A [ i ] = = B [ j ] m a x { d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] } ,   A [ i ] ! = B [ j ] dp[i][j]=\begin{cases} dp[i-1][j-1]+1,\ A[i]==B[j]\\max\{dp[i-1][j],dp[i][j-1] \},\ A[i]!=B[j]\end{cases} dp[i][j]={dp[i1][j1]+1, A[i]==B[j]max{dp[i1][j],dp[i][j1]}, A[i]!=B[j]
边界条件: d p [ i ] [ 0 ] = d p [ 0 ] [ j ] = 0 ( 0 ⩽ i ⩽ n , 0 ⩽ j ⩽ n ) dp[i][0]=dp[0][j]=0(0\leqslant i\leqslant n,0\leqslant j\leqslant n) dp[i][0]=dp[0][j]=0(0in,0jn)

4.最长回文子串

给出一个子串 S S S,求出其最长回文子串的长度
步骤1: 令状态 d p [ i ] [ j ] dp[i][j] dp[i][j]表示 S [ i ] 和 S [ j ] S[i]和S[j] S[i]S[j]所表示的子串是否为回文子串,是则为1,不是则为0;
步骤2: 讨论两种情况
1 ◯ \text{\textcircled 1} 1 S [ i ] = = S [ j ] S[i]==S[j] S[i]==S[j],则只要 S [ i + 1 ] − S [ j − 1 ] S[i+1]-S[j-1] S[i+1]S[j1]是回文串,则 S [ i ] − S [ j ] S[i]-S[j] S[i]S[j]就是,否则都不是
2 ◯ \text{\textcircled 2} 2 S [ i ] ! = S [ j ] S[i]!=S[j] S[i]!=S[j],那么 S [ i ] − S [ j ] S[i]-S[j] S[i]S[j]一定不是回文串
由此可得,状态转移方程为:
d p [ i ] [ j ] = { d p [ i + 1 ] [ j − 1 ] , S [ i ] = = S [ j ] 0 , S [ i ] ! = S [ j ] dp[i][j]=\begin{cases}dp[i+1][j-1],S[i]==S[j]\\ 0,S[i]!=S[j]\end{cases} dp[i][j]={dp[i+1][j1],S[i]==S[j]0,S[i]!=S[j]
边界: d p [ i ] [ i ] = 1 , d p [ i ] [ i + 1 ] = ( S [ i ] = = S [ i + 1 ] ) ? 1 : 0 dp[i][i]=1,dp[i][i+1] =(S[i]==S[i+1])?1:0 dp[i][i]=1,dp[i][i+1]=(S[i]==S[i+1])?1:0
按照枚举子串长度,按照子串长度遍历计算每个状态,如不按照子串长度遍历,状态方程会无法转移

for(int L =3;L<=len;L++){//枚举子串长度
		for(int i=0;i+L-1<len;i++){
				int j =i+L-1;
			}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值