一个h*w 的竖直平面,有n个间物品,每个物品是1*wi,要尽量往上放,问应该放在哪。
线段树真是奇妙~
主要是题目规定了必须要尽量往上放,不然就是个贪心了~
区间的含义是[l,r]行中可以放的位置最大的空间,那就是点修改,点查询了
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 200000 + 10;
int maxv[maxn<<2],n,h,w,x;
void build(int rt,int L,int R){
maxv[rt] = w;
if(L == R) return ;
int mid = (L+R)>>1;
build(rt<<1,L,mid);
build(rt<<1|1,mid+1,R);
}
int query(int rt,int L,int R,int x){
if(L == R) {
maxv[rt] -= x;
return L;
}
int mid = (L+R)/2;
int ans = (maxv[rt<<1]>=x? query(rt<<1,L,mid,x):query(rt<<1|1,mid+1,R,x));
maxv[rt] = max(maxv[rt<<1],maxv[rt<<1|1]);
return ans;
}
int main(){
while(~scanf("%d%d%d",&h,&w,&n)){
if(h>n) h = n;
build(1,1,h);
for(int i = 0;i<n;i++){
scanf("%d",&x);
if(maxv[1]<x) printf("-1\n");
else printf("%d\n",query(1,1,h,x));
}
}
return 0;
}
604

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



