トピック
東洞には2つのシーケンスAとBがあります。
彼は、シーケンスAのLISとシーケンスABのLCSの長さを知りたいと考えています。
LISは厳密に増加している、つまりa1 <a2 <... <ak(ai <= 1,000,000,000)であることに注意してください。
入力
最初の行の2つの数字n、m(1 <= n <= 5,000,1 <= m <= 5,000)
2行目のnの数は、シーケンスAを表します。
3行目のmの数は、シーケンスBを表します。
出力
シーケンスAのLISとシーケンスABのLCSの長さをそれぞれ表すデータans1とans2の行を出力します。
簡単な入力
5 5
1 3 2 5 4
2 4 3 1 5
シンプルな出力
3 2
アイデア
エラー
1. nとmを入力するのを忘れました。2。f
[i] [j]を計算するときに、以前のf [i] [j]がすでに計算されているため、この質問に再帰を使用する必要はありません。ネストされたforループを使用するだけです。
コード
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
//可能需要二分orz
const int maxn=5010;
long long a[maxn];
long long b[maxn];
int f[maxn];
int f2[maxn][maxn]={
};
int main()
{
int n,m,ans1=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=1;i<=m;i++)
scanf("%lld",&b[i]);
//LIS 最长上升子序列
f[1]=1;
for(int i=2;i<=n;i++)
{
int maxx=0;
for(int j=1;j<i;j++)
{
if(a[j]<a[i]&&f[j]>maxx)
maxx=f[j];
}
f[i]=maxx+1;
}
for(int i=1;i<=n;i++)
if(f[i]>ans1)
ans1=f[i];
cout<<ans1<<' ';
f2[1][0]=0;
f2[0][1]=0;
f2[0][0]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(a[i]==b[j])
f2[i][j]=f2[i-1][j-1]+1;
else
f2[i][j]=max(f2[i-1][j],f2[i][j-1]);
}
cout<<f2[n][m]<<endl;
return 0;
}