array array array
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 610 Accepted Submission(s): 352
Kiddo: "I have an array A and a number k , if you can choose exactly k elements from A and erase them, then the remaining array is in non-increasing order or non-decreasing order, we say A is a magic array. Now I want you to tell me whether A is a magic array. " Conan: "emmmmm..." Now, Conan seems to be in trouble, can you help him?
1≤T≤20
1≤n≤105
0≤k≤n
1≤Ai≤105
3 4 1 1 4 3 7 5 2 4 1 3 1 2 6 1 1 4 3 5 4 6
A is a magic array. A is a magic array. A is not a magic array.
题意就没什么可说的了,意思就是给你 n 个数字的序列,然后让你删 k 个数字,问你删完之后能不能让这个序列变成非递增或非递减序列,可以的话,这个序列就是magic序列,否则不是。
注意:非递增序列可以像这样:1 1 1,而不是递增序列的序列则有别于非递增序列,像:1 1 1 是不属于不是递增序列的序列的,像 1 3 2 才是不是递增序列的序列,比如:
6 2
1 4 3 5 4 6。
这个序列就是magic序列,因为把 3 和 5 删掉之后就是了。
然后说说思路,这题就是要你求最长递增递减子序列,其实,递增序列反过来就是递减序列。但是用传统的求法时间复杂度是O(n^2),于是就得用二分法,具体的步骤可以上网搜:“最长上升子序列 nlog(n)”,然后你就会看到很多大佬的博客上面有了。
附上代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
typedef long long LL;
///o(っ。Д。)っ AC万岁!!!!!!!!!!!!!!
const int maxn = 100090, inf = 0x7fffffff;
int maps[maxn] = {}, aa[maxn] = {}, book[maxn] = {};
int binary_searchs(int l, int r, int k)
///这里就是优化后的方法了
{
if(l == r) return l;
int mid = (l + r + 1) / 2;
if(book[mid] >= k)
{
return binary_searchs(l, mid - 1, k);
}
else
{
return binary_searchs(mid, r, k);
}
}
int main()
{
int _;
scanf("%d", &_);
while(_--)
{
int n, k;
scanf("%d %d", &n, &k);
for(int i = 1; i <= n; i++)
{
scanf("%d", &maps[i]);
aa[n - i + 1] = maps[i];
}
int ans = 1;
book[1] = maps[1];
for(int i = 2; i <= n; i++)
{
if(maps[i] >= book[ans])
{
book[++ans] = maps[i];
}
else
{
int gg = binary_searchs(1, ans, maps[i]) + 1;
book[gg] = min(book[gg], maps[i]);
}
}
int cnt = 0;
book[cnt] = aa[1];
for(int i = 1; i <= n; i++)
{
if(aa[i] >= book[cnt])
{
book[++cnt] = aa[i];
}
else
{
int gg = binary_searchs(1, cnt, aa[i]);
book[gg] = min(book[gg], aa[i]);
}
}
if(n - ans <= k || n - cnt <= k)
{
printf("A is a magic array.\n");
}
else printf("A is not a magic array.\n");
}
return 0;
}
/*
7 6
1 4 13 5 8 7 9
*/
本文介绍了一个有趣的编程问题:如何判断一个序列在删除指定数量元素后能否成为非递增或非递减序列。通过实例说明了问题背景,并给出了使用二分查找优化后的最长递增子序列算法解决方案。
1004

被折叠的 条评论
为什么被折叠?



