12.4拦截导弹(北京大学复试)

问题分类:动态规划法 + 最长递增子序列问题

dp[i]取值的两种可能

  1. nums[i]之前的元素都比i大,即最长的递归子序列只有nums[i]本身,那么dp[i] = 1
  2. nums[i]之前存在numsj比nums[i]大,那么dp[i] = dp[j]+1;

状态转移方程为:

dp[i] = max(1, dp[j] +1) 其中 j为 满足(j<i && nums[j] > nums[i])的全部的j 因为有很多个j,循环时应写成,dp[i] = 1, dp[i] = max(dp[i], dp[j] +1);

ans = max(dp[i], ans);

#include<vector>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<int> nums(n),dp(n);
	for (int i = 0; i < n; i++) {
		cin >> nums[i];
	}
	int ans = 0;
	for (int i = 0; i < n; i++) {
		dp[i] = 1;
		for (int j = 0; j < i; j++) {
			if (nums[j] >= nums[i]) {
				dp[i] = max(dp[j] + 1, dp[i]);
			}
		}
		ans = max(ans, dp[i]);
	}
	cout << ans << endl;
	return 0;
}