最长严格上升子序列
这就是基础的线性dp了(咱们就不讨论 平方暴力做法了)
int main() {
IOS; cin >> n;
rep (i, 1, n) f[i] = 1e9;
rep (i, 1, n) {
cin >> a[i];
int cur = upper_bound(f + 1, f + 1 + n, a[i]) - f;
cout << a[i] << ' ' << cur << '\n';
f[cur] = a[i]; umax(ans, cur);
}
cout << ans;
return 0;
}
最少改几个数,可以使 a[i] 非严格上升
那不就是长度减去 非严格上升子序列的长度吗?
int main() {
IOS; cin >> n;
rep (i, 1, n) f[i] = 1e9;
rep (i, 1, n) {
cin >> a[i];
int cur = upper_bound(f + 1, f + 1 + n, a[i]) - f;
cout << a[i] << ' ' << cur << '\n';
f[cur] = a[i]; umax(ans, cur);
}
cout << n - ans;
return 0;
}
最少改几个数, 可以使得 a[i] 严格上升
想想和上面的联系,严格和非严格 有啥区别?
a[i] < a[i + 1] 和 a[i] <= a[i + 1]
我们默认先让 a[i+1] 比 a[i] 小 1 , a[i] < a[i + 1] 不就成了 a[i] <= a[i + 1] 了吗?
(现 a[i+1] = 原 a[i+1] - 1), 每个数都这样, 不就是 a[i] - i 吗?
即 1~n a[i] -= i, 就成了上个问题
int main() {
IOS; cin >> n;
rep (i, 1, n) f[i] = 1e9;
rep (i, 1, n) {
cin >> a[i]; a[i] -= i;
int cur = upper_bound(f + 1, f + 1 + n, a[i]) - f;
cout << a[i] << ' ' << cur << '\n';
f[cur] = a[i]; umax(ans, cur);
}
cout << n - ans;
return 0;
}
CF 1437E Make It Increasing
主菜来了, 先把不能找出来的直接 return 掉
什么情况不行呢? 首先是不然改的序列存在 a[b[i]] > a[b[i + 1]], 或者不让改的两个数之间放不下 a[b[i+ 1]] - a[b[i]]
然后是怎么处理 不能改的位置 (我就到这步卡住的)
其实我们注意到, 只有被选入 f[i] 才有可能不被修改, 当然 f[ans] 肯定是不会被修改的
怎么让 f[i] 也不被修改呢? 每次替换只能替换 当前最近的不能修改的位置之后的数就好了 (没想到这个, 我是sb)
int main() {
IOS; cin >> n >> m; f[0] = -2e9;
rep(i, 1, n) cin >> a[i];
rep(i, 1, m) {
cin >> b[i]; v[b[i]] = 1;
if (i == 1) continue;
if (b[i] < b[i - 1] || a[b[i]] - a[b[i - 1]] < b[i] - b[i - 1])
cout << -1, exit(0);
}
rep(i, 1, n) {
a[i] -= i;
if (f[ans] <= a[i]) {
f[++ans] = a[i];
if (v[i]) k = ans;
}
else {
int cur = upper_bound(f + 1, f + 1 + ans, a[i]) - f;
if (cur <= k) continue;
f[cur] = a[i];
if (v[i]) k = ans = cur;
}
}
cout << n - ans;
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。