12.4拦截导弹(北京大学复试)
问题分类:动态规划法 + 最长递增子序列问题
dp[i]取值的两种可能
- nums[i]之前的元素都比i大,即最长的递归子序列只有nums[i]本身,那么dp[i] = 1
- 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;
}