这道题相信各位都是用了常见的动态规划模板,最长上升子序列,本蒟蒻对着样的解法写出了2个版本,第二个有了微乎其微的优化,时间更少。首先一个最长上升子序列双向,然后各种凑求最大值。伪代码来一发(中文,类似于《算法导论》)
for i=1到n
for j=0到i-1
如果a[i]>a[j]
那么f[i]=较大(f[i],f[j]+1);
//f维护动态规划。
再来一个从后往前的实现方法同上。//用f1数组维护
for i=1到n
ans=较大(ans,f[i]+f1[i]-1);
输出n-ans;
如果只是想理一理思路的,看到这里就可以结束了,如果想抄袭具体借鉴一下的请往下看
最长上升子序列
for(i=1;i<=n;i++)
for(j=0;jif(a[i]>a[j])
f[i]=max(f[i],f[j]+1);
//这边要特别注意从第一位的后面以为开始,即从f[0]开始,不然会出现bug。
找最大值
for(i=1;i<=n;i++)
ans=max(ans,f[i]+f1[i]-1);
整体的 BY CPP
#include
using namespace std;
int f[110],a[110],f1[110];
bool x;
int main()
{
int n,i,j,k,ans;
cin>>n;
f[1]=1;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
for(j=0;jif(a[i]>a[j])
f[i]=max(f[i],f[j]+1);
for(i=n;i>=1;i--)
for(j=n+1;j>i;j--)
if(a[i]>a[j])
f1[i]=max(f1[i],f1[j]+1);
//cout<
for(i=1;i<=n;i++)
ans=max(ans,f[i]+f1[i]-1);
cout<return 0;
}
部分可以优化伪代码再来一发
for i=1到n
{
int bigger=0;//保存最大值
for j=1到a[i]
取较大值
f[a[i]]=mx+1
这是不降子序列,来自《算法导论》模板,要改成上升,还要,稍作改动,如还有不懂,可以私信我。