最长递增子序列(nlogn):#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int x[500010],a[500010];
int main()
{
int n,Z=0;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
x[a]=b;
}//序列
a[1]=x[1];//a数组存储最长的递增子序列
int len=1;
for(int i=2;i<=n;i++)
{
int L=1,R=len;
while(L<=R)//用二分找当前数在a数组中的位置
{
int mid=(L+R)/2;
if(x[i]>a[mid])
L=mid+1;
else
R=mid-1;
}
a[L]=x[i];//更新a数组
if(L>len)//如果加长数组则数组长度加一
len++;
}
printf("Case %d:\n",++Z);
if(len==1)
printf("My king, at most 1 road can be built.\n\n");
else
printf("My king, at most %d roads can be built.\n\n",len);
}
}
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int x[500010],a[500010];
int main()
{
int n,Z=0;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
x[a]=b;
}//序列
a[1]=x[1];//a数组存储最长的递增子序列
int len=1;
for(int i=2;i<=n;i++)
{
int L=1,R=len;
while(L<=R)//用二分找当前数在a数组中的位置
{
int mid=(L+R)/2;
if(x[i]>a[mid])
L=mid+1;
else
R=mid-1;
}
a[L]=x[i];//更新a数组
if(L>len)//如果加长数组则数组长度加一
len++;
}
printf("Case %d:\n",++Z);
if(len==1)
printf("My king, at most 1 road can be built.\n\n");
else
printf("My king, at most %d roads can be built.\n\n",len);
}
}
最长公共子串(连续):#include<cstdio>//正确性有待考证
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int dp[1010][1010];//dp[i][i]表示a,b字符串分别以i,j为终点的最长公共子串长度;
int main()
{
int ncase;
cin>>ncase;
while(ncase--)
{
memset(dp,0,sizeof(dp));
int END,stare;//END记录最长公共子串的结束下标,stare记录开始下标;
string a,b;
cin>>a>>b;
int al=a.size();
int bl=b.size();
for(int i=0; i<al; i++)
if(a[0]==b[i])
dp[0][i]=1;
for(int i=0; i<bl; i++)
if(b[0]==a[i])
dp[i][0]=1;
//预处理数组越界
int Max=0;
for(int i=1; i<al; i++)
for(int j=1; j<bl; j++)
{
if(a[i]==b[j])//字符相等
{
// if(i==0||j==0)
// dp[i][j]=1;
// else
//如果加上循环从0开始,不用预处理
dp[i][j]=dp[i-1][j-1]+1;//前一个长度+1;
}
else
dp[i][j]=0;//不相等就为0;
if(dp[i][j]>Max)//更新最大值,终点.
{
Max=dp[i][j];
END=j;
}
}
// stare=END-Max+1;
// for(int i=stare;i<=END;i++)//输出最长公共子串
// printf("%c",b[i]);
// printf("\n");
printf("%d\n",Max);
}
}
#include<cstdio>//正确性有待考证
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int dp[1010][1010];//dp[i][i]表示a,b字符串分别以i,j为终点的最长公共子串长度;
int main()
{
int ncase;
cin>>ncase;
while(ncase--)
{
memset(dp,0,sizeof(dp));
int END,stare;//END记录最长公共子串的结束下标,stare记录开始下标;
string a,b;
cin>>a>>b;
int al=a.size();
int bl=b.size();
for(int i=0; i<al; i++)
if(a[0]==b[i])
dp[0][i]=1;
for(int i=0; i<bl; i++)
if(b[0]==a[i])
dp[i][0]=1;
//预处理数组越界
int Max=0;
for(int i=1; i<al; i++)
for(int j=1; j<bl; j++)
{
if(a[i]==b[j])//字符相等
{
// if(i==0||j==0)
// dp[i][j]=1;
// else
//如果加上循环从0开始,不用预处理
dp[i][j]=dp[i-1][j-1]+1;//前一个长度+1;
}
else
dp[i][j]=0;//不相等就为0;
if(dp[i][j]>Max)//更新最大值,终点.
{
Max=dp[i][j];
END=j;
}
}
// stare=END-Max+1;
// for(int i=stare;i<=END;i++)//输出最长公共子串
// printf("%c",b[i]);
// printf("\n");
printf("%d\n",Max);
}
}
最长公共子序列(不连续):#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int dp[1010][1010];
int main()
{
int ncase;
scanf("%d",&ncase);
while(ncase--)
{
memset(dp,0,sizeof(dp));
string a,b;
cin>>a;
b=a;
reverse(b.begin(), b.end());//倒置字符串
int l=a.size();
for(int i=0;i<l;i++)//l为a的长度
for(int j=0;j<l;j++)//l为b的长度
if(a[i]==b[j])
dp[i+1][j+1]=dp[i][j]+1;
else
dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
printf("%d\n",l-dp[l][l]);//dp[l][l]为a和b最长公共子序列;
}
}
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int dp[1010][1010];
int main()
{
int ncase;
scanf("%d",&ncase);
while(ncase--)
{
memset(dp,0,sizeof(dp));
string a,b;
cin>>a;
b=a;
reverse(b.begin(), b.end());//倒置字符串
int l=a.size();
for(int i=0;i<l;i++)//l为a的长度
for(int j=0;j<l;j++)//l为b的长度
if(a[i]==b[j])
dp[i+1][j+1]=dp[i][j]+1;
else
dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
printf("%d\n",l-dp[l][l]);//dp[l][l]为a和b最长公共子序列;
}
}