此为最长非递增子序列问题,可以开两层循环求n-LIS(Longest Non-Increasing Subsequence)问题 可以用两层循环确定其数组。
也可以用DP。其本质思想是一样的。DP的写法高大上一些。
下面分别给出C++ 和Java 的实现过程
C++:
//此题要求每一发炮弹只能小于上一发炮弹的高度
#include<cstdio>
int high[22];
int maxLen[22];
void LCS(int n) //最长非递增子序列函数
{
for(int i=0;i<n;++i)//遍历其前所有导弹高度
{
maxLen[i] = 1;
for(int j=0;j<i;++j)
{
if(high[j]>=high[i])//如果当前导弹高度小于等于j号导弹
{
int preMax = maxLen[j]+1;//把当前导弹放在j号导弹后,其最长不增子序列长度为j号导弹结尾的最长不增子序列长度 + 1
if(preMax>maxLen[i])
{
maxLen[i] = preMax;
}
}
}
}
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
int m;
scanf("%d",&m);
for(int i=0;i<m;++i)
scanf("%d",&high[i]);
LCS(m);
int max = -1;
for(int i=0;i<m;++i)
{
if(maxLen[i]>max)
{
max = maxLen[i];
}
}
printf("%d\n",max);
}
return 0;
}
Java:
package nyOJ;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main1079_DP
{
public static void main(String[] args) throws IOException
{
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(stdin.readLine());
int[] ans = new int[1010];
for (int t=0; t<n; ++t)
{
int m = Integer.parseInt(stdin.readLine());
String[] mid = stdin.readLine().split(" ");
for (int i=0; i<=m; ++i)
{
ans[i] = 1;
for (int j=0; j<i; ++j)
{//下面要把i==m条件放在前面,这样可以最后一次循环(i==m成立时)截断后面的条件,否则后面的条件存在下标越界
if(i==m||Integer.parseInt(mid[j])>Integer.parseInt(mid[i]))//i==m是为最后遍历整个数组,求最大值
ans[i] = Math.max(ans[j]+1, ans[i]);
}
}
System.out.println(ans[m]-1);
}
}
}
/*
2
8
389 207 155 300 299 170 158 65
3
88 34 65
*/