ACM自用模板

目录

1 动态规划(DP)

1.1 最长上升子序列(LIS)

1.1.1 O(n^2)

1.1.2 O(nlogn)

1.2 最长公共子序列(LCS)

1.3区间DP


1 动态规划(DP)

1.1 最长上升子序列(LIS)

1.1.1 O(n^2)

//求到第i位的最长子串长度
for (int i=0;i<len;i++)
{
	//自己的长度1
	dp[i]=1;
	for (int j=0;j<i;j++)
	{
		//第i位比第j位大更新dp[i]
		if (s[i]>s[j])    
			dp[i]=max(dp[j]+1,dp[i]); 
	}
	//更新答案
	if (dp[i]>ans)
		ans=dp[i];
}

//ans即答案
cout << ans << endl;

1.1.2 O(nlogn)

//初始化dp为inf=0x3f3f3f
memset(dp,inf,sizeof(dp));

for (int i=0;i<len;i++)
{
        //获取位置
        int pos=lower_bound(dp,dp+len,s[i])-dp;
        //更新位置
        dp[pos]=s[i];
        ans=max(ans,pos);
}

//答案为ans+1
cout << ans+1 << endl;

1.2 最长公共子序列(LCS)

//len1和len2为两字符串长度
for (int i=1;i<=len1;i++)
	for (int j=1;j<=len2;j++)
		//相等时直接更新
		if (s1[i-1]==s2[j-1])
			dp[i][j]=dp[i-1][j-1]+1;
		//不相等时继承之前的最大值
		else
			dp[i][j]=max(dp[i-1][j],dp[i][j-1]);

//答案为dp[len1][len2]
cout << dp[len1][len2] << endl;

1.3区间DP

//初始化DP数组
for (int i=1;i<=n;i++)
	dp[i][i]=INF(0 or 其他)

//枚举区间长度
for (int len=1;len<n;len++)
	//枚举起点
	for (int i=1;i+len<=n;i++)
	{
		//区间终点
		int j=i+len;
		//枚举分割点
		for (int k=i;k<j;k++)
			dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+w[i][j]);
	}

//区间1-n的结果
cout << dp[1][n] << endl;

 

posted on 2018-11-03 17:03  Radium_1209  阅读(129)  评论(0)    收藏  举报

导航