我在 spoj 上尝试了这个问题。首先,我想出了一种微不足道的 o(blogb) 算法(请参阅问题的什么 b)。但是由于问题的作者提到了 b 属于 [0,10^7] 的约束,我不相信如果它会通过。无论如何,出于剪切信念,我将其编码如下
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<cstdlib>
#include<stack>
#include<queue>
#include<string>
#include<cstring>
#define PR(x) cout<<#x"="<<x<<endl
#define READ2(x,y) scanf("%d %d",&x,&y)
#define REP(i,a) for(long long i=0;i<a;i++)
#define READ(x) scanf("%d",&x)
#define PRARR(x,n) for(long long i=0;i<n;i++)printf(#x"[%d]=\t%d\n",i,x[i])
using namespace std;
#include <stdio.h>
struct node {
int val;
int idx;
};
bool operator<(node a,node b){ return a.val<b.val;}
node contain[10000001];
int main(){
int mx=1,count=1,t,n;
scanf("%d",&t);
while(t--){
count=1;mx=1;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&contain[i].val);
contain[i].idx=i;
}
sort(contain,contain+n);
for(int j=1;j<n;j++){
if(contain[j].idx>contain[j-1].idx)
count++;
else count=1;
mx=max(count,mx);
}
printf("%d\n",n-mx);
}
}
它在 SPOJ 服务器上以 0.01 秒通过(已知速度很慢)但我很快想出了一个 O(b) 算法,代码如下
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<cstdlib>
#include<stack>
#include<queue>
#include<string>
#include<cstring>
#define PR(x) printf(#x"=%d\n",x)
#define READ2(x,y) scanf("%d %d",&x,&y)
#define REP(i,a) for(int i=0;i<a;i++)
#define READ(x) scanf("%d",&x)
#define PRARR(x,n) for(int i=0;i<n;i++)printf(#x"[%d]=\t%d\n",i,x[i])
using namespace std;
int val[1001];
int arr[1001];
int main() {
int t;
int n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
int mn=2<<29,count=1,mx=1;
for(int i=0;i<n;i++){
scanf("%d",&arr[i]);
if(arr[i]<mn) { mn=arr[i];}
}
for(int i=0;i<n;i++){
val[arr[i]-mn]=i;
}
for(int i=1;i<n;i++){
if(val[i]>val[i-1]) count++;
else {
count=1;
}
if(mx<count) mx=count;
}
printf("%d\n",n-mx);
}
}
但令人惊讶的是它花了0.14 秒:O
现在我的问题是o(b) 不是比 o(blogb) 更好 b > 2吗?那为什么时间差这么大?社区的一位成员建议这可能是由于缓存未命中。与 o(blogb) 相比,o(b) 代码的本地化程度较低。但我认为对于 <1000运行代码?(是的b实际上小于1000。不知道为什么问题设置者夸大了这么多)
编辑:我看到所有答案都指向渐近符号中的隐藏常数值,这通常会导致算法运行时间的差异。但是如果你查看代码,你会意识到我所做的只是用另一个遍历替换排序调用的循环。现在我假设 sort 至少访问数组的每个元素一次。如果我们考虑执行的行数,这不会使两个程序更接近吗?除了是的,我过去使用 spoj 的经验告诉我 I/O对程序的运行时间产生巨大影响,但我在两个代码中使用相同的 I/O 例程。