您的位置:首页 > 其它

Light OJ 1084 线段树+dp or(单调队列+dp) 水题

2013-06-12 18:03 288 查看
2B错误,线段树开了2倍空间, 检查到死,改成4倍空间直接AC,太伤了,线段树太弱了。

线段树:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define Mid int m = (l+r) >> 1;
const int maxn = 100005;
const int inf = 1e9;
int n, k;
int a[maxn];
int dp[maxn];

struct segtree {
int sum[maxn<<2];
void pushUp(int rt) {
sum[rt] = min(sum[rt<<1], sum[rt<<1|1]);
}
void build(int l = 0, int r = n, int rt = 1) {
sum[rt] = inf;
if(l == r) {
if(l == 0) sum[rt] = 0;
return;
}
Mid;
build(lson);
build(rson);
pushUp(rt);
}
void insert(int p, int v, int l = 0, int r = n, int rt = 1) {
if(l == r) {
sum[rt] = min(sum[rt], v);
return;
}
Mid;
if(p <= m) insert(p, v, lson);
else insert(p, v, rson);
pushUp(rt);
}
int query(int L, int R, int l = 0, int r = n, int rt = 1) {
if(L <= l && r <= R)
return sum[rt];
Mid;
int ret = inf;
if(L <= m) ret = min(ret, query(L, R, lson));
if(R > m) ret = min(ret, query(L, R, rson));
return ret;
}
void print(int l = 0, int r = n, int rt = 1) {
if(l ==r) {
printf("%d ", sum[rt]);
return;
}
Mid;
print(lson);
print(rson);
}
}T;

int main() {
// freopen("int.txt", "r", stdin);
int i, j, d, cas;
scanf("%d", &cas);
for(int ca = 1; ca <= cas; ca++) {
scanf("%d%d", &n, &k);
for(i = 1; i <= n; i++) {
scanf("%d", &a[i]);
dp[i] = inf;
}
T.build();
dp[0] = 0;
sort(a+1, a+n+1);
for(i = 1; i <= n; i++) {
j = lower_bound(a+1, a+i+1, a[i]-(k<<1))-a;
//printf("i = %d j = %d\n", i, j);
if(i-j+1 >= 3) {
// puts("YES");
dp[i] = min(dp[i], T.query(j-1, i-3) + 1);
T.insert(i, dp[i]);
}
}
if(dp
>= inf) dp
= -1;
printf("Case %d: %d\n", ca, dp
);
}
return 0;
}

单调队列:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define Mid int m = (l+r) >> 1;
const int maxn = 100005;
const int inf = 1e9;
int n, k;
int a[maxn];
int dp[maxn];

int Q[maxn];
int main() {
// freopen("int.txt", "r", stdin);
int i, j, d, cas;
scanf("%d", &cas);
for(int ca = 1; ca <= cas; ca++) {
scanf("%d%d", &n, &k);
for(i = 1; i <= n; i++) {
scanf("%d", &a[i]);
dp[i] = -1;
}
sort(a+1, a+n+1);
dp[0] = 0;
int len = k<<1;

int s = 0, e = 0;
for(i = 1; i <= n; i++) {
int t = i-3;
if(t >= 0 && ~dp[t]) {
while(s < e && dp[Q[e-1]] > dp[t]) e--;
Q[e++] = t;
}

while(s < e && a[Q[s]+1] + len < a[i]) s++;
if(s != e) dp[i] = dp[Q[s]]+1;
}
printf("Case %d: %d\n", ca, dp
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: