Problem A: 景观调整
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 256 Solved: 17
[ Submit][ Status][ Web Board]
Description
埃森哲的一楼大厅有一处景观,景观有一排等宽的木条组成的篱笆,木条的高度各异,一共有n块。我们从左往右依次编号木条为1到n,则木条的长度可以用数列A1,A2,A3...,An来表示(Ai代表编号i木条的高度)。
有一天,小Q的上级经理从北京来参观,觉得这段篱笆景观实在是太丑了,于是他决定做一点改变。根据经理的美学观点,有序是最美的,所以他想通过一些木条的替换使得整个篱笆从左到右高度严格递增,同时也象征公司业绩节节高升。
篱笆是不允许有漏洞的,换句话说就是不存在Ai <= 0。这个任务现在就交给小Q了。
当然,如你所知,小Q是一个特别精打细算的人,已知替换木条的费用并不与替换与被替换木条的高度有关,只简单的与总替换次数有关,现在胡小Q想知道最少替换几个木条就能使得整个篱笆具有高度的美学价值。
Input
包含多组测试数据。每组数据两行。
对于每组数据:
第一行:一个整数n(1 <= n <= 100,000)。
第二行:输入n个正整数A1,A2,A3...An(Ai <= 1000,000,000)。
Output
对于每组测试数据,输出一行,包含一个整数,代表最少替换几个木条就能满足要求。
Sample Input
3
1 2 3
4
1 2 2 3
1 2 3
4
1 2 2 3
Sample Output
0
2
2
HINT
第一组:原始序列已经有序,不需要任何修改。
第二组:将A3改为3,A4改为4即可满足要求。
这道题的难点在于,整数这个条件。
假如没有整数这个条件,我们求一次最长上升子序列即可。
为了避开整数这个条件,我们先预处理,A`(i) = A(i) - i。这样我们再求最长非降子序列即可。新序列A`(i)满足不减,则原数列对应地满足A(i) >= A(i-1)+1。
题目范围过大,需要用二分优化。
一开始以为是差分约束系统,但是差分约束系统求出来很多组解,难以知道哪个解与原问题距离最近。
这道题的难点在于,整数这个条件。
假如没有整数这个条件,我们求一次最长上升子序列即可。
为了避开整数这个条件,我们先预处理,A`(i) = A(i) - i。这样我们再求最长非降子序列即可。新序列A`(i)满足不减,则原数列对应地满足A(i) >= A(i-1)+1。
题目范围过大,需要用二分优化。
一开始以为是差分约束系统,但是差分约束系统求出来很多组解,难以知道哪个解与原问题距离最近。
#include <cstdio>
#include <cstring>
#include <string>
using std::min;
using std::max;
int ans = 0;
int s[100010];
int h[100010];
int find(int hh)
{
int l = 0;
int r = ans;
int mid;
int rs = 0;
while (l <= r)
{
mid = (l+r)/2;
if (s[mid] <= hh)
{
l = mid + 1;
if (rs < mid)
rs = mid;
}
else
r = mid - 1;
}
return rs;
}
int main()
{
int n;
bool first = true;
while (scanf("%d",&n)==1)
{
if (!first) printf("\n");
first = false;
ans = 0;
memset(s,0x3f,sizeof s);
s[0] = 0;
for (int i=1;i<=n;i++)
{
scanf("%d",h+i);
h[i] -= i;
}
for (int i=1;i<=n;i++)
{
if (h[i] < 0) continue;
int f = find(h[i]) + 1;
//f = max(f,i);
ans = max(ans,f);
s[f] = min(s[f],h[i]);
}
printf("%d",n-ans);
}
return 0;
}