【Luogu 1799】数列

题目描述

虽然msh长大了,但她还是很喜欢找点游戏自娱自乐。有一天,她在纸上写了一串数字:1,l,2,5,4。接着她擦掉了一个l,结果发现剩下l,2,4都在自己所在的位置上,即1在第1位,2在第2位,4在第4位。她希望擦掉某些数后,剩下的数列中在自己位置上的数尽量多。她发现这个游戏很好玩,于是开始乐此不疲地玩起来……不过她不能确定最多能有多少个数在自己的位置上,所以找到你,请你帮忙计算一下!

输入输出格式

输入格式:

第一行为一个数n,表示数列的长度。

接下来一行为n个用空格隔开的正整数,第i行表示数Ai。

输出格式:

一行一个整数,表示擦掉某些数后,最后剩下的数列中最多能有多少个数在自己的位置上,即Ai=i最多能有多少。

输入输出样例

输入样例#1:
5
1 1 2 5 4
输出样例#1:
3

说明

对于20%的数据,n≤20;

对于60%的数据,n≤100;

对于100%的数据,n≤l000。

我傻,一看题就只会一维dp,然而题解里都是二维的

那还是一维吧
因为本题其实只与去掉的数的个数有关,所以一维就够
如果已知去掉i-1个数时,最多有dp[i-1]个满足条件,
那么如果再去掉最后一个数,此时最多有dp[i-1]+1(当最后加进来的一个数刚好就是和他的次序数一致时)个数满足条件
#include<bits/stdc++.h>
using namespace std;
int a[1010],n,ans;
int dp[1010];//表示剩余j个时 
//最多能有  个满足条件 
void init()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>a[i];
}
void DP() 
{
	for(int i=1;i<=n;i++)
	{
		for(int j=i;j>=1;j--)
			dp[j]=max(dp[j],dp[j-1]+(a[i]==j?1:0));
	}//然后,找到最大的
	for(int i=0;i<=n;i++) 
	ans=max(ans,dp[i]);
}
int main()
{
	init();
	DP();
	cout<<ans<<endl;
	return 0;
} 
G102的孤儿们都要好好的啊。
原文地址:https://www.cnblogs.com/ve-2021/p/9255425.html