洛谷P3902题解:最长递增子序列的贪心优化
一、问题背景
洛谷P3902题目要求计算使序列变为严格递增序列所需的最小修改次数。通过转化为最长递增子序列问题,我们可以高效解决这一难题。
二、算法核心思想
三、完整代码实现(带详细注释)
#include <bits/stdC++.h> using namespACe std; const int MAXN = 1e5+5; // 定义最大数组长度 int main() { ios::sync_with_stdio(false); // 加速输入输出 cin.tie(0); // 解除cin与cout的绑定 int n; cin >> n; vector<int> nums(n); for(int i=0; i<n; i++) { cin >> nums[i]; // 读取输入序列 } // 计算最长递增子序列长度 vector<int> dp; // 维护的可能LIS序列 for(int num : nums) { // 使用lower_bound找到第一个不小于当前元素的位置 auto it = lower_bound(dp.begin(), dp.end(), num); if(it == dp.end()) { dp.push_back(num); // 当前元素大于所有元素,扩展序列 } else { *it = num; // 替换第一个不小于当前元素的元素 } } // 输出需要修改的次数 cout << n - dp.size() << endl; return 0; }
四、关键步骤解析
lower_bound函数:在有序序列中二分查找插入位置
维护dp数组:始终保持dp数组的递增性和最小末尾元素
替换策略:用更小的元素替换原有元素,为后续元素创造更多可能
五、学习建议
先理解传统DP解法
手动模拟小规模数据
尝试实现其他LIS变种问题
练习相关题目巩固理解
原创内容 转载请注明出处