HDU 5188
这题我已不想吐槽自己了。第一反应就是个01背包,也就是加了些限制。开始时按 l 排序,按01的来写,呵呵,输出数组时才发现不对。后来改为按 l-t即最早开始时间排,OK。但自己手贱竟然写了个线段树要快速返回前面大的值。2B啊,既然按最早开始时间加入,那分值必定是按顺序递增的啊,根本就没必啊。。。所以,只需排序后按裸01来做就可以了。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define LL __int64 using namespace std; const int N=200010; LL ret; LL tree[N*4]; LL temp[N]; struct Node{ int v,l,t,es; bool operator<(const Node &a) const{ if(es<a.es)return true; return false; } }node[35]; void search(int root,int L,int R,int l,int r){ if(L<=l&&r<=R){ ret=max(ret,tree[root]); return ; } int m=(l+r)>>1; if(L<=m) search(root*2,L,R,l,m); if(m<R) search(root*2+1,L,R,m+1,r); } void update(int root,int L,int R,int l,int r,LL maxv){ if(L<=l&&r<=R){ tree[root]=maxv; return ; } int m=(l+r)>>1; if(L<=m) update(root*2,L,R,l,m,maxv); if(m<R) update(root*2+1,L,R,m+1,r,maxv); // tree[root]=max(tree[root*2],tree[root*2+1]); } int main(){ LL w; int n; int v,t,l; LL sum; int mt,ll; while(scanf("%d%I64d",&n,&w)!=EOF){ mt=ll=-1; sum=0; for(int i=0;i<n;i++){ scanf("%d%d%d",&t,&v,&l); node[i].l=l; node[i].es=l-t; node[i].v=v; node[i].t=t; mt=max(mt,t); ll=max(ll,l); sum+=v; } if(sum<w){ printf("zhx is naive!\n"); continue; } sort(node,node+n); memset(tree,0,sizeof(tree)); memset(temp,0,sizeof(temp)); for(int i=0;i<n;i++){ for(int j=ll+mt;;j--){ if(j<node[i].l) break; if(j-node[i].t<0) break; // ret=-1; // search(1,0,j-node[i].t,0,ll+mt); // cout<<ret<<endl; if(temp[j-node[i].t ]+node[i].v>temp[j]){ temp[j]=temp[j-node[i].t]+node[i].v; // update(1,j,j,0,ll+mt,temp[j]); } } /* for(int k=0;k<=ll+mt;k++) cout<<temp[k]<<" "; cout<<endl;*/ } int i; for(i=0;i<=ll+mt;i++){ if(temp[i]>=w){ printf("%d\n",i); break; } } if(i>ll+mt) printf("zhx is naive!\n"); } return 0; }