最长递减子序列「掘金日新计划 · 12 月更文挑战」

111 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

[为什么是送分题]

题目描述

一个体力为无穷大的肉战士,现在想要从家乡到帝都出人头地,在路上会遇到 n 个狂战士,每次遇到狂战士,肉战士可以选择战斗或者不战,狂战士非常凶残,与之战斗只有当己方的体力比狂战士的体力高的话才能打败狂战士,即使打败后自己的体力也只会剩下和狂战士初始的体力一样,反之被打死。为了能使肉战士能出人头地,他希望他能打败更多的狂战士,问他最多能打败多少狂战士。
注:肉战士和狂战士都能透支体力即使体力为负值也能行动,但是被杀死就没了。

输入格式

两行,第一行输入一个数 n (1 ≤ n ≤ 10^3)表示狂战士的数量,第二行输入一个长度为 n 的数组 nums (-10^9 ≤ nums[i] ≤ 10^9),以空格分隔,表示狂战士的体力。

输出格式

一行,输出满足要求的答案。

样例

输入数据 1

5
1 3 5 4 7

输出数据 1

2

思路

首先看到题目要求输入最多能打败的狂战士,中途还可以选择不打,所以证明不需要连续,其次如果我在中途就把体力弄成负的了,那么后面的选择就会越来越少,由此得出,我们需要找最长递减子序列,子序列不需要连续,这个时候就该想到最长递减子序列的板子。(qwq...如果没有的话建议备一个)

代码

#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0)
using namespace std;
const int N = 1e3+10;
int a[N];
int dp[N];
void solve(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>a[i];
	for(int i=0;i<=n;i++)dp[i] = 1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<i;j++){
			if(a[i]<a[j])dp[i] = max(dp[i],dp[j]+1);
		}
	}
	int mx = 0;
	for(int i=1;i<=n;i++)mx = max(mx,dp[i]);
	cout<<mx<<endl;
}
signed main(){
    IOS;
	solve();
	return 0;
}