Weighted items knapsack problem

Perhaps a better reading experience

\ (\ mathcal {Description} \
) have \ (n-\) th items, each item has a weight \ (W_i \) and weight \ (V_I \) , and to the additional \ (m \) backpacks, each has a capacity backpack.
You need to select several items, and selecting an equal number of these items will be loaded into the backpack, the backpack each can only be installed a article requires each knapsack capacity greater than equal to the weight of the article.
Next, you need to these backpacks from left to right in a row. If any adjacent two backpacks, backpack items are left to meet the weight does not exceed had the right backpack weight items, while the value of items left in the backpack does not exceed the value of the right backpack items.
Q can pick out the maximum number of items so as to satisfy the condition
\ (n, m \ leq 10 ^ 5 \)

\(\mathcal{Solution}\)

First article according to \ (W \) in ascending order
and descending considering the article knapsack
disposed \ (F_i \) represented by \ (I \) No. articles as at the beginning of the longest sequence length
account of the \ (I \) when one article, may be put to find the minimum of the backpack, which is larger than the number can be calculated with a backpack, to \ (NUM \)
then \ (f_i = \ min (num , \ max \ {f_ {i + k} \}) \)
with the segment tree or tree-like array to maintain maximum suffix
or prefix turn into descending order to maintain maximum

\(\mathcal{Code}\)

/*******************************
Author:Morning_Glory
LANG:C++
Created Time:2019年11月02日 星期六 09时57分32秒
*******************************/
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cstring>
#define w first
#define v second
#define lbt(x) x&-x
#define reset(x) memset(x,0,sizeof(x))
using namespace std;
const int maxn = 200005;
//{{{cin
struct IO{
    template<typename T>
    IO & operator>>(T&res){
        res=0;
        bool flag=false;
        char ch;
        while((ch=getchar())>'9'||ch<'0')   flag|=ch=='-';
        while(ch>='0'&&ch<='9') res=(res<<1)+(res<<3)+(ch^'0'),ch=getchar();
        if (flag)   res=~res+1;
        return *this;
    }
}cin;
//}}}
int T,n,m,totw,totv;
int p[maxn],tw[maxn],tv[maxn],c[maxn],f[maxn];
pair<int,int> a[maxn];
//{{{init
void init ()
{
    cin>>n;
    for (int i=1;i<=n;++i)  cin>>a[i].w>>a[i].v,tw[i]=a[i].w,tv[i]=a[i].v;
    cin>>m;
    for (int i=1;i<=m;++i)  cin>>p[i],tw[i+n]=p[i];

    sort(tw+1,tw+n+m+1);
    sort(tv+1,tv+n+1);
    totw=unique(tw+1,tw+n+m+1)-tw-1;
    totv=unique(tv+1,tv+n+1)-tv-1;

    for (int i=1;i<=n;++i)
        a[i].w=lower_bound(tw+1,tw+totw+1,a[i].w)-tw,
        a[i].v=lower_bound(tv+1,tv+totv+1,a[i].v)-tv;

    sort(a+1,a+n+1);

    for (int i=1;i<=m;++i)  p[i]=lower_bound(tw+1,tw+totw+1,p[i])-tw;
    sort(p+1,p+m+1);

    while (a[n].w>p[m]) --n;
}
//}}}
//{{{modify
void modify (int x,int v)
{
    for (;x;x-=lbt(x))  c[x]=max(c[x],v);
}
//}}}
//{{{query
int query (int x)
{
    int s=0;
    for (;x<=totv;x+=lbt(x))    s=max(s,c[x]);
    return s;
}
//}}}
//{{{solve
void solve ()
{
    reset(f),reset(c);
    for (int i=n;i;--i){
        int num=lower_bound(p+1,p+m+1,a[i].w)-p;
        num=m-num+1;
        f[a[i].v]=max(f[a[i].v],min(query(a[i].v)+1,num));
        modify(a[i].v,f[a[i].v]);
    }
    int ans=0;
    for (int i=1;i<=totv;++i)   ans=max(ans,f[i]);
    printf("%d\n",ans);
}
//}}}
int main()
{
    cin>>T;
    while (T--){
        init();
        solve();
    }
    return 0;
}

If not quite understand where to put it or there is an error, please correct me
if you like, you may wish to point a collection of praise about it

Guess you like

Origin www.cnblogs.com/Morning-Glory/p/11783238.html