题目传送门https://www.luogu.com.cn/problem/P1799
解题思路
本题可使用暴力……
暴力
这是暴力代码:
表示以第
个数结尾,序列长度为
。
#include<bits/stdc++.h>
using namespace std;
int n;
int a[1001];
int f[1001][1001];
int ans;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
if(a[1]==1)
f[1][1]=1;
for(int i=2;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
for(int k=1;k<i;k++)
{
f[i][j]=max(f[i][j],f[k][j-1]);
}
if(a[i]==j)
f[i][j]++;
ans=max(ans,f[i][j]);
}
}
cout<<ans;
return 0;
}
正解
嗯嗯,当然,万一数据过强,那暴力肯定是过不了的……
所以,要思考正解。
设 表示前
个数,删除
个数的最大序列长度。
那么,对于第 个数,可以删除或不删除:
对于不删除:
对于删除:
取最大值即可。
代码
#include<bits/stdc++.h>
using namespace std;
int n;
int a[1001];
int f[1001][1001];
int ans;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
{
f[i][0]=f[i-1][0];
if(a[i]==i)
f[i][0]++;
for(int j=1;j<=i;j++)
{
f[i][j]=max(f[i][j],max(f[i-1][j]+(a[i]==i-j),f[i-1][j-1]));
ans=max(ans,f[i][j]);
}
ans=max(ans,f[i][0]);
}
cout<<ans;
return 0;
}