[贪心 归并排序] BZOJ 2920 [Poi1998]How to pack containers

来源:互联网 发布:linux 给用户权限 编辑:程序博客网 时间:2024/05/29 19:05

 对于容器从小到大考虑,首先将体积为i的方案与已有方案利用归排合并,然后若当前的方案不足T[i]个则无解,否则选取前T[i]个加两合并作为下一次的方案。


#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;typedef pair<int,int> abcd;inline char nc(){  static char buf[100000],*p1=buf,*p2=buf;  if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }  return *p1++;}inline void read(int &x){  char c=nc(),b=1;  for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;  for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}const int N=10005;int n,m;abcd a[N];int cnt[N];int Ans=0;int lst[N];int tmp1[N],tmp2[N];inline void Merge(int *a,int *b,int *ret){  *ret=0;  int n1=*a,n2=*b,p1=1,p2=1;  a[++n1]=-1<<30; b[++n2]=-1<<30;  while (p1<n1 || p2<n2)    ret[++*ret]=a[p1]>b[p2]?a[p1++]:b[p2++];  a[n1--]=0; b[n2--]=0;}int main(){  int iu,iv=0;  freopen("t.in","r",stdin);  freopen("t.out","w",stdout);  read(n);  for (int i=1;i<=n;i++) read(a[i].first),read(a[i].second);  sort(a+1,a+n+1);  read(m);  for (int i=1;i<=m;i++) read(iu),read(cnt[iu]),iv=max(iv,iu);  int pnt=1,flag=0;  for (int i=0;i<=iv && !flag;i++){    *tmp2=0;    while (a[pnt].first==i) tmp2[++*tmp2]=a[pnt++].second;    reverse(tmp2+1,tmp2+*tmp2+1);    Merge(lst,tmp2,tmp1);    for (int j=0;j<=*tmp1;j++) lst[j]=tmp1[j];    if (cnt[i]>*lst)      flag=1;    else{      for (int j=1;j<=cnt[i];j++)Ans+=lst[*lst-j+1];      *lst-=cnt[i];      *tmp2=0;      for (int i=*lst;i && i-1;i-=2)tmp2[++*tmp2]=lst[i]+lst[i-1];      for (int i=0;i<=*tmp2;i++)lst[i]=tmp2[i];      reverse(lst+1,lst+*lst+1);    }  }  if (flag)    printf("NIE\n");  else    printf("%d",Ans);  return 0;}


0 0
原创粉丝点击