分治背包-01背包模板

去掉每一个物品,在v体积下的最大获利。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define maxn 1050
#define maxm 300500
using namespace std;
int n,x,y,z,m,ans[maxm];
vector <int> linker[maxn],val[maxn],a;
struct point
{
    int l,r,v,w;
    point (int l,int r,int v,int w):l(l),r(r),v(v),w(w){}
};
vector <point> v;
void DC(int l,int r,vector <point> v,vector <int> a)
{
    int mid=l+r>>1;
    vector <point> x,y;
    for (int i=0;i<v.size();i++)
    {
        point now=v[i];
        if ((now.l==l) && (now.r==r))
        {
            for (int j=maxn;j>=now.v;j--)
                a[j]=max(a[j],a[j-now.v]+now.w);
        }
        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));
            y.push_back(point(mid+1,now.r,now.v,now.w));    
        }    
    }
    if (l==r)
    {
        for (int i=0;i<linker[l].size();i++)
            ans[linker[l][i]]=a[val[l][i]];
        return;
    }
    DC(l,mid,x,a);
    DC(mid+1,r,y,a);
}
int main()
{
    freopen("chisa.in","r",stdin);
    freopen("chisa.out","w",stdout);
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        if (i!=1) v.push_back(point(1,i-1,x,y));
        if (i!=n) v.push_back(point(i+1,n,x,y));
    }
    for (int i=0;i<=maxn;i++) a.push_back(0);
    scanf("%d",&m);
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        x++;
        linker[x].push_back(i);val[x].push_back(y);
    }
    DC(1,n,v,a);
    for (int i=1;i<=m;i++) printf("%d
",ans[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/ziliuziliu/p/6054447.html