ACM自用模板
目录
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) 收藏 举报
浙公网安备 33010602011771号