数列【DP】
题目描述
虽然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≤1000。
分析:首先看数据范围,OK,设计一个O(n^2)的算法。设f【i】表示1到i中满足条件的最大个数。想了一下方程,不对啊,不能完全表示信息,在看一看时间复杂度,那就多加一维吧,f【i】【j】,表示什么呢?我们需要什么信息?删除了多少个数,对吧。所以设f【i】【j】表示1到i中删除j个数满足条件的最大个数。方程不难想到,具体见代码。答案为max(f【n】【k】)(0<=k<=n)。
#include<cstdio>
#include<iostream>
using namespace std;
int n,a[1010],f[1010][1010];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&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 i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
if(a[j]+i==j)
{
f[j][i]=max(f[j-1][i-1],f[j-1][i]+1);
}
else f[j][i]=max(f[j-1][i-1],f[j-1][i]);
}
}
int ans=0;
for(int i=0;i<=n;i++)
ans=max(ans,f[n][i]);
printf("%d",ans);
return 0;
}
谢谢各位
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构