洛谷 U141580 简化罗波切问题
题目背景
SeawaySeawaySeaway突然回想起很久很久以前,大约在2013年,他的死党小学同学yhbyhbyhb和他探讨的小学奥数问题:罗波切问题。这个问题是一个类似于数独的矩阵问题。由于SeawaySeawaySeaway没有学过小学奥数,当时这个问题为难了他好久。
SeawaySeawaySeaway在美滋滋地回忆的同时,想简化一下罗波切问题。
题目描述
于是他推出了罗波切问题的简化版。他把罗波切问题由一个矩阵问题简化成一个数列问题。这个问题大体是这样的:对于一个给定数列来讲,它成为罗波切数列,当且仅当这个数列里的所有数严格单调递增。需要注意的是:对于无穷级数的情况,它成为罗波切数列,当且仅当这个数列的通项是满足任二点通导均为正数。那么,对于一个给定数列来讲,改变它的一些数,使得它成为罗波切数列的最少修改次数就是它的罗波切解。求一个数列罗波切解的问题被称作罗波切问题。
现在请你解决这个问题。
输入格式
第一行一个整数NNN,表示数列长度。
第二行NNN个整数,描述原始数列。
输出格式
一行一个整数ansansans,表示给定数列的罗波切解。如果无解,请输出Impossible
。
命题背景:
稍微回忆一下,当初被爆锤的回忆。
题解:
单调队列不仅仅能维护滑动窗口。
反正这道题给我的意义就是:以后碰到单调一些的题,先试试单调数据结构,看看能不能解,然后再去想什么其他解法。
这道题就是,不是要维护单调吗?好啊!那我就维护一个单调队列,对于新入队元素,大了当然好,小于等于的,就在单调队列里找一个小于等于他的,把它塞进去就行。这就是一次修改的过程。
代码:
#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;
int n,q[100010],now,ans;
signed main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
int num;
scanf("%lld",&num);
if(num>q[now])
q[++now]=num;
else
{
*lower_bound(q+1,q+now+1,num)=num;
ans++;
}
}
printf("%lld",ans);
return 0;
}