现在的位置: 首页 > 综合 > 正文

hdu 2795 Billboard

2018年04月21日 ⁄ 综合 ⁄ 共 1026字 ⁄ 字号 评论关闭

这题想清楚了 就很简单。。想不清楚就蛋疼。反正我是蛋疼了2天

给你一块矩阵 高h 宽w

然后给n 个 高 1 宽 x 的小矩阵

按题意放 能不能放下海报

h * w 可以看成 h 个节点每个节点长度为w 

这样小矩阵的高度就可以忽略了 只要考虑x

按题意 贴入海报 其实就是对节点进行删除x长度操作

然后都是从最左边开始找 

父节点存的是子节点 最大长度 

tree[1].v 存的就是所有节点中最大的长度

如果x > tree[1].v 那么就代表 无法贴入海报

在n个海报都可以插入 的情况下, 最坏的情况是每个海报的x = w ,那么最多只需要 n 的节点就可以了

所以当h > n 的时候 只需要n 个节点

如果h <= n 那么最好的情况也只能插入h个

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int const MAXN = 200010;
#define Lson l,m,rt<<1
#define Rson m+1,r,rt<<1|1
struct Tree{
    int l,r;
    int v;
}tree[MAXN<<2];
void Build(int w,int l,int r,int rt){
    tree[rt].v = w;
    if(l == r) return ;
    int m = (l + r)>>1;
    Build(w,Lson);
    Build(w,Rson);
}
inline int Max(int a,int b){
    return a>b?a:b;
}
inline void PushUp(int rt){
    tree[rt].v = Max(tree[rt<<1].v,tree[rt<<1|1].v);
}
int Query(int w,int l,int r,int rt){
    if(l == r){
        tree[rt].v -= w;
        return l;
    }
    int m = (l + r)>>1;
    int ret = 0;
    if(w <= tree[rt<<1].v) ret = Query(w,Lson);
    else ret = Query(w,Rson);
    PushUp(rt);
    return ret;
}
int main(){
    int h,w,n;
    while(~scanf("%d%d%d",&h,&w,&n)){
        if(h > n) h = n;
        Build(w,1,h,1);
        for(int i = 1;i <= n;i++){
            int x;
            scanf("%d",&x);
            if(tree[1].v < x) printf("-1\n");
            else printf("%d\n",Query(x,1,h,1));
        }
    }
    return 0;
}

 

抱歉!评论已关闭.