此为最长非递增子序列问题,可以开两层循环求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 */