• BZOJ 3163 Eden的新背包问题


    分治背包+单调队列优化。

    但是为什么maxn要1w多?。。。不怎么懂。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<cstdlib>
    #define maxn 10050
    #define maxs 1050
    #define maxm 300500
    using namespace std;
    int n,x,y,z,m,ans[maxm],up[maxn],q[maxn],vals[maxn],l,r;
    struct point
    {
        int l,r,v,w,c;
        point (int l,int r,int v,int w,int c):l(l),r(r),v(v),w(w),c(c){}
    };
    vector <point> v;
    vector <int> dp,linker[maxn],val[maxn];
    int read()
    {
        int data=0;char ch;
        while (ch<'0' || ch>'9') ch=getchar();
        while (ch>='0' && ch<='9')
        {
            data=data*10+ch-'0';
            ch=getchar();
        }
        return data;
    }
    void insert(int x,int y,int v,int w,vector <int> & dp)
    {
        while ((l<=r) && (vals[r]<=dp[x]-y*w)) r--;
        q[++r]=x;vals[r]=dp[x]-y*w;
    }
    void DC(int left,int right,vector <point> v,vector <int> dp)
    {
        int mid=left+right>>1;
        vector <point> x,y;
        for (int i=0;i<v.size();i++)
        {
            point now=v[i];
            if ((now.l==left) && (now.r==right))
            {
                for (int j=0;j<=maxs%now.v;j++) up[j]=maxs/now.v*now.v+j;
                for (int j=maxs%now.v+1;j<now.v;j++) up[j]=(maxs/now.v-1)*now.v+j; 
                for (int j=0;j<now.v;j++)
                {
                    l=1;r=0;int ret=up[j],lim=up[j],ret1=up[j]/now.v,ret2=up[j]/now.v;
                    while (ret>=0)
                    {
                        while ((l<=r) && (q[l]>ret)) l++;
                        while ((lim>=ret-now.c*now.v) && (lim>=0))
                        {
                            insert(lim,ret2,now.v,now.w,dp);
                            lim-=now.v;ret2--;
                        }
                        dp[ret]=vals[l]+ret1*now.w;
                        ret1--;ret-=now.v;
                    }
                }
            }
            else if (now.r<=mid) x.push_back(now);
            else if (now.l>=mid+1) y.push_back(now);
            else 
            {
                x.push_back(point(now.l,mid,now.v,now.w,now.c));
                y.push_back(point(mid+1,now.r,now.v,now.w,now.c));
            }
        }
        if (left==right)
        {
            for (int i=0;i<linker[left].size();i++)
                ans[linker[left][i]]=dp[val[left][i]];
            return;
        }
        DC(left,mid,x,dp);
        DC(mid+1,right,y,dp);
    }
    int main()
    {
        n=read();
        for (int i=1;i<=n;i++)
        {
            x=read();y=read();z=read();
            if (i!=1) v.push_back(point(1,i-1,x,y,z));
            if (i!=n) v.push_back(point(i+1,n,x,y,z));
        }
        for (int i=0;i<=maxn;i++) dp.push_back(0);
        m=read();
        for (int i=1;i<=m;i++)
        {
            x=read();y=read();x++;
            linker[x].push_back(i);val[x].push_back(y); 
        }
        DC(1,n,v,dp);
        for (int i=1;i<=m;i++) printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    linux下/proc/sysrq-trigger文件的功能
    Windows下bat命令
    转——802.11协议
    转 ——eclipse下进行Python开发 环境配置
    U盘装centos7系统过程
    django框架介绍
    2-事件之间关系(概率论与数理统计学记笔记)
    1-基本概念(概率论与数理统计学习笔记)
    舆情正负面判断

  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6055758.html
Copyright © 2020-2023  润新知