L. Longest Array Deconstruction

L. Longest Array Deconstruction

https://codeforces.com/contest/1575/problem/L

题目大意

给出一组数a,你可以删除任意数,要求在任意次操作后的数组中满足a[i]==i的数量最大。

解题思路

考虑dp,首先枚举删除的数量,即数的移动次数,对于第i个数,如果a[i]>i则此数无法对答案造成贡献,因为i只能减少,所以无法得到a[i]=i,故初始时只需要i>=a[i]的情况即可。

很显然的转移方程是移动次数多的状态可以由移动次数少的状态转移,所以从小到大枚举每个位置的移动次数,对于第i个位置的值ai,答案即是dp[ai]=max1jai1dp[j]+1dp[i]表示以i结尾的答案。所以dp[n]即使最终结果。

这里可以使用树状数组维护和更新最大值来求dp值。

Code

#include <bits/stdc++.h>
#define lowbit(x) x&-x
const int  N = 2e5+7;

using namespace std;

int a[N];
set<int>v[N];
int tree[N];
void add(int i,int y){
	while(i < N){
		tree[i] = max(tree[i], y);
		i += lowbit(i);
	}
}


int getsum(int i)
{
	int res = 0;
	while(i > 0){
		res = max(res, tree[i]);
		i -= lowbit(i);
	}
	return res;
}

void solve()
{
	int n;
	scanf("%d",&n);
	for(int i = 1; i <= n;i++){
		scanf("%d",&a[i]);
		if(i - a[i] >= 0)
			v[i - a[i]].insert(a[i]);
	}
	int ans = 0;
	for(int i = 0; i < N; i++){
		for(int j : v[i]){
			ans = (getsum(j-1));
			add(j, ans + 1);
		}
	}
	printf("%d\n",getsum(n));

}

int  main()
{
	solve();	
	return 0;
}
posted @   !^^!  阅读(147)  评论(0编辑  收藏  举报
编辑推荐:
· 探秘 MySQL 索引底层原理,解锁数据库优化的关键密码(下)
· 大模型 Token 究竟是啥:图解大模型Token
· 35岁程序员的中年求职记:四次碰壁后的深度反思
· 继承的思维:从思维模式到架构设计的深度解析
· 如何在 .NET 中 使用 ANTLR4
阅读排行:
· 在线聊天系统中的多窗口数据同步技术解密
· 2025,回顾出走的 10 年
· 分享 3 款基于 .NET 开源且免费的远程桌面工具
· BotSharp 5.0 MCP:迈向更开放的AI Agent框架
· 【保姆级教程】windows 安装 docker 全流程
点击右上角即可分享
微信分享提示