zoukankan      html  css  js  c++  java
  • HDU5808Price List Strike Back (BestCoder Round #86 E) cdq分治+背包

    严格按题解写,看能不能形成sum,只需要分割当前sum怎么由两边组成就好

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <vector>
    #include <algorithm>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int N = 2e4+100;
    int f[N][105],g[N][105];
    int ret[N*5],v[N],d[N],T,n,m;
    struct Que
    {
        int l,r,c,sum,id;
    } p[N*5];
    void cdq(int l,int r,int x,int y)
    {
        int mid=(l+r)>>1;
        vector<Que>lf,rt,cur;
        lf.clear(),rt.clear(),cur.clear();
        for(int i=x; i<=y; ++i)
        {
            if(p[i].l>mid)rt.push_back(p[i]);
            else if(p[i].r<mid)lf.push_back(p[i]);
            else cur.push_back(p[i]);
        }
        if(cur.size())
        {
            for(int i=0; i<=100; ++i)f[mid][i]=g[mid][i]=INF;
            f[mid][v[mid]]=d[mid];
            for(int i=mid-1; i>=l; --i)
            {
                for(int j=0; j<=100; ++j)
                {
                    if(j>=v[i])
                    {
                        if(j-v[i]==0)f[i][j]=min(f[i+1][j],d[i]);
                        else f[i][j]=min(f[i+1][j],max(f[i+1][j-v[i]],d[i]));
                    }
                    else f[i][j]=f[i+1][j];
                }
            }
            for(int i=mid+1; i<=r; ++i)
            {
                for(int j=0; j<=100; ++j)
                {
                    if(j>=v[i])
                    {
                        if(j-v[i]==0)g[i][j]=min(g[i-1][j],d[i]);
                        else g[i][j]=min(g[i-1][j],max(g[i-1][j-v[i]],d[i]));
                    }
                    else g[i][j]=g[i-1][j];
                }
            }
            for(int i=0; i<cur.size(); ++i)
            {
                if(cur[i].r==mid)
                {
                    if(f[cur[i].l][cur[i].sum]>cur[i].c)ret[cur[i].id]=1;
                    continue;
                }
                bool flag=false;
                for(int j=0; j<=cur[i].sum; ++j)
                {
                    int dis;
                    if(!j)dis=g[cur[i].r][cur[i].sum-j];
                    else if(j==cur[i].sum)dis=f[cur[i].l][j];
                    else dis=max(f[cur[i].l][j],g[cur[i].r][cur[i].sum-j]);
                    if(dis<=cur[i].c)
                    {
                        flag=true;
                        break;
                    }
                }
                if(!flag)ret[cur[i].id]=1;
            }
        }
        int cnt=x-1;
        if(lf.size())
        {
            for(int i=0; i<lf.size(); ++i)
                p[++cnt]=lf[i];
            cdq(l,mid,x,cnt);
        }
        if(rt.size())
        {
            x=cnt+1;
            for(int i=0; i<rt.size(); ++i)
                p[++cnt]=rt[i];
            cdq(mid+1,r,x,cnt);
        }
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n; ++i)scanf("%d",&v[i]);
            for(int i=1; i<=n; ++i)scanf("%d",&d[i]);
            for(int i=1; i<=m; ++i)
            {
                scanf("%d%d%d%d",&p[i].l,&p[i].r,&p[i].c,&p[i].sum);
                p[i].id=i;
                ret[i]=0;
            }
            cdq(1,n,1,m);
            for(int i=1; i<=m; ++i)printf("%d",ret[i]);
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    链表
    Wonder团队承接各种Web3D业务
    真我的信息
    一个人独自做长期项目,如何提高工作效率?
    【Java】类的结构
    【长知识】找书攻略
    【长知识】语义化版本控制
    【Java】Debug调试常用技巧
    【Web】Servlet三大作用域、JSP四大作用域
    【Web】Servlet基本概念
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5747478.html
Copyright © 2011-2022 走看看