最长公共上升子序列

我的想法:

f[i][j]表示以i结尾的a与j结尾的b的最长公共子序列 状态转移方程

\[f[i][j]=max\{f[k][l]\}+1 \]

时间复杂度:\(O(n^4)\)

我们要分析最长上升子序列,就必须分析最后一位,因此状态里要包含最后一位. 但是注意到这道题的特殊条件

a[i]和b[j]在成立的时候始终是相等的,而且是公共子序列,这样就会造成状态的浪费.因为记录下来最后一位就会设计到枚举的过程,时间复杂度增加,并且没有办法用状态集合优化

用一个变量存储合法决策集合 也就是满足转移条件的状态集合

每次尝试边界条件的那一个值就可以

for(int i=1;i<=n;i++)
{
	f[1][i]=(a[1]==b[i]);
	f[i][1]=(a[i]==b[1]);
}
	
for(int i=2;i<=n;i++)
{
	int val=b[1]<a[i]?f[i-1][1]:0;//存储1-(j-1)的决策集合 
	for(int j=2;j<=n;j++)
	{
		if(a[i]==b[j]) f[i][j]=val+1;
		else f[i][j]=f[i-1][j];
		if(b[j]<a[i]) val=max(val,f[i-1][j]);
	}	
}

值得注意的技巧:

  1. 提出条件 属于减掉常数
  2. 能够使用判断边界来优化决策集合的条件是: 条件在改变的时候只改变边界 条件相对固定
  3. 动态规划复杂度过高 还有可能是状态设计不够优美
posted @ 2022-02-08 13:54  __iostream  阅读(38)  评论(0)    收藏  举报