Backpack nine stresses, wrote to his

Prior to learn dp not properly read through the backpack nine stresses, today talked about the backpack nine again, after watching for some of their own convenience.

 


 

A. 01 backpack

  Topic link: https: //www.acwing.com/problem/content/2/

  n,V<=1000

  Say nothing of this, plus the scroll array, the complexity O (nV), the following code:

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=1e3+5;
int n,V,dp[maxn],v[maxn],w[maxn];

int main(){
    scanf("%d%d",&n,&V);
    for(int i=1;i<=n;++i)
        scanf("%d%d",&v[i],&w[i]);
    for(int i=1;i<=n;++i)
        for(int j=V;j>=v[i];--j)
            dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
    printf("%d\n",dp[V]);
    return 0;
}
View Code

  Note that, if the subject of restrictions must be filled, it should dp array is initialized to negative infinity, only dp [0] is initialized to 0, this time dp [i] is defined as the maximum value for the size of a backpack full of i the rest are the same, the answer is dp [V].

 


 

II. Backpack full

  Topic link: https: //www.acwing.com/problem/content/3/

  n,V<=1000

  Only the order of j is traversed from the backpack 01 to reverse the order changed, the complexity O (nV). code show as below:

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=1e3+5;
int n,V,v[maxn],w[maxn],dp[maxn];

int main(){
    scanf("%d%d",&n,&V);
    for(int i=1;i<=n;++i)
        scanf("%d%d",&v[i],&w[i]);
    for(int i=1;i<=n;++i)
        for(int j=v[i];j<=V;++j)
            dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
    printf("%d\n",dp[V]);
    return 0;
}
View Code

  Similarly, if the subject would fill limit, the array initialization dp is negative infinity, only dp [0] = 0.

 


 

III. Multiple backpack

 

1. Multiple backpack I (O (nVs))

Topic link: https: //www.acwing.com/problem/content/4/

n kinds of goods, v [i], w [i], s [i] respectively represent the volume of items i, and the value of the number, size backpack V, seeking the maximum value. n, V, s <= 100.

In the backpack 01 on the basis of one cycle plus a few items selected from the group represented by i, i.e. dp [j] = max (dp [j], dp [jk * v [i]] + k * w [i]), k = 1 ..s [i].

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=105;
int n,V,v[maxn],w[maxn],s[maxn],dp[maxn];

int main(){
    scanf("%d%d",&n,&V);
    for(int i=1;i<=n;++i)
        scanf("%d%d%d",&v[i],&w[i],&s[i]);
    for(int i=1;i<=n;++i)
        for(int j=V;j>=v[i];--j)
            for(int k=1;k<=s[i]&&k*v[i]<=j;++k)
                dp[j]=max(dp[j],dp[j-k*v[i]]+k*w[i]);
    printf("%d\n",dp[V]);
    return 0;
}
View Code

 

2. Multiple backpack II-- binary Optimized (O (nVlogs))

Topic link: https: //www.acwing.com/problem/content/5/

And the meaning of the title is the same as above, except that the data changed range, n <= 1000, V, s <= 2000.

If the practices described in the previous question, the complexity is 4e9, properly properly T fly.

First, each item conceivable to split into s [i] an article 01 can be solved knapsack, then there is a 1000 × 2000 = 2e6 article, by a V, the complexity 4e9, QAQ. .

Next, the binary power, the number of articles of s [i] into a number 2 K 0 , 2 1 ... 2 K , K = log 2 s [i], then use these numbers may represent 1 to s any number [i] is so reduced complexity to O (nVlogs). But note that for 7, we break down into 1,2,7 is no problem for 10, we can not be broken down into 1,2,4,8, because this represents the number may be more than 10, then the situation we the last number as s [i] - and the front, i.e. 1,2,4,3 represented by 10. Since s [i] <= 2000 < 2048, so the number can be represented using up to 11 s [i]. Complexity is 2e7.

Code:

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=1005*11+5;
int n,V,cnt,v[maxn],w[maxn],dp[maxn];

int main(){
    scanf("%d%d",&n,&V);
    for(int i=1;i<=n;++i){
        int vv,ww,ss;
        scanf("%d%d%d",&vv,&ww,&ss);
        for(int j=1;j<=ss;j*=2){
            v[++cnt]=vv*j;
            w[cnt]=ww*j;
            ss-=j;
        }
        if(ss){
            v[++cnt]=vv*ss;
            w[cnt]=ww*ss;
        }
    }
    for(int i=1;i<=cnt;++i)
        for(int j=V;j>=v[i];--j)
            dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
    printf("%d\n",dp[V]);
    return 0;
}
View Code

 

3. Multiple backpack III (O (nV))

Topic link: https: //www.acwing.com/problem/content/description/6/

The meaning of problems remained the same, the data range becomes n <= 1000, V, s <= 20000. In this case said binary optimized O (nVlogs) approaches also fail. Monotone considered at this point to optimize the queue, remove the complexity of the logs.

  The most primitive state of multiple backpack transfer equation:

  Order c [i] = min (num [i], j / v [i]), f [i] [j] = max (f [i-1] [jk * v [i]] + k * w [ i]) (1 <= k <= c [i]) k where is the i-th item pointing member k.

  If we let a = j / v [i], b = j% v [i] then j = a * v [i] + b. Where k represents a change in meaning, k denotes a ratio of the number of i-th element takes a few small items.

  那么 f[i][j] = max(f[i-1][b+k*v[i]] - k*w[i]) + a*w[i]      (a-c[i] <= k <= a)

  Can be found in, f [i-1] [b + k * v [i]] - k * w [i] is only a relationship with k, and this k is a contiguous (as long as the state equation dp problem can be expressed in such a way, can be used to optimize the monotonous queue). We have to do is to obtain f [i-1] [b + k * v [i]] - k * w [i] takes the maximum value within the feasible interval k. Therefore, we can mold by j v [i] to divide the remainder, respectively monotonous queue solved.

AC Code:

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=1005;
const int maxv=20005;
int n,V,dp[maxv],q1[maxv],q2[maxv];
int head,tail;

int main(){
    scanf("%d%d",&n,&V);
    for(int i=1;i<=n;++i){
        int v,w,s;
        scanf("%d%d%d",&v,&w,&s);
        for(int j=0;j<v;++j){
            head=1,tail=0;
            for(int k=j,num=0;k<=V;k+=v,++num){
                int tmp=dp[k]-num*w;
                while(head<=tail&&tmp>=q1[tail]) --tail;
                q1[++tail]=tmp;
                q2[tail]=num;
                while(num-q2[head]>s) ++head;
                dp[k]=q1[head]+num*w;
            }
        }
    }
    printf("%d\n",dp[V]);
    return 0;
}
View Code

 


 

IV. Mixed knapsack problem

Topic link: https: //www.acwing.com/problem/content/7/

Meaning of the questions: Comprehensive The first three issues, namely, an article could be 01 backpack, may be completely backpack, backpack may be multiple.

The multiple backpack only O (nV) solution to slightly change it, i.e., if s = -1, so s = 1, if s = 0, so s = V / v, as other cases.

AC Code:

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=1005;
const int maxv=1005;
int n,V,dp[maxv],q1[maxv],q2[maxv];
int head,tail;

int main(){
    scanf("%d%d",&n,&V);
    for(int i=1;i<=n;++i){
        int v,w,s;
        scanf("%d%d%d",&v,&w,&s);
        if(s==-1) s=1;
        else if(s==0) s=V/v;
        for(int j=0;j<v;++j){
            head=1,tail=0;
            for(int k=j,num=0;k<=V;k+=v,++num){
                int tmp=dp[k]-num*w;
                while(head<=tail&&tmp>=q1[tail]) --tail;
                q1[++tail]=tmp;
                q2[tail]=num;
                while(num-q2[head]>s) ++head;
                dp[k]=q1[head]+num*w;
            }
        }
    }
    printf("%d\n",dp[V]);
    return 0;
}
View Code

 


 

V. expense of two-dimensional knapsack problem

Topic link: https: //www.acwing.com/problem/content/8/

The meaning of problems: on the basis of increasing the maximum load of the backpack 01 M backpack, each item has three attributes v, m, w, i.e. volume, weight and value, only one of each item.

Thinking: Thinking and 01 as a backpack, only increases one dimension, with dp [i] [j] represents a space is i, the maximum value for the load of the backpack j, then add a layer represents the weight is circulated, V and M They were descending traverse. Complexity of O (nVM).

AC Code:

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxv=105;
int n,V,M,dp[maxv][maxv];

int main(){
    scanf("%d%d%d",&n,&V,&M);
    for(int i=1;i<=n;++i){
        int v,m,w;
        scanf("%d%d%d",&v,&m,&w);
        for(int j=V;j>=v;--j)
            for(int k=M;k>=m;--k)
                dp[j][k]=max(dp[j][k],dp[j-v][k-m]+w);
    }
    printf("%d\n",dp[V][M]);
    return 0;
}
View Code

Similarly, full knapsack knapsack problem solving and multi-dimensional cost of the backpack is also similar to the front.

 


 

VI. Grouping backpack

Topic link: https: //www.acwing.com/problem/content/9/

Meaning of the questions: n items in the group, backpacks volume V. Each article has s [i] th article is selected from each group up to an article. Q. maximum value.

Thinking: backpack with multiple similar, but at most one item is selected from each group, with the layer 3 is circulated. Complexity is O (nVs), no optimization.

AC Code:

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=105;
int n,V,s[maxn],v[maxn][maxn],w[maxn][maxn],dp[maxn];

int main(){
    scanf("%d%d",&n,&V);
    for(int i=1;i<=n;++i){
        scanf("%d",&s[i]);
        for(int j=1;j<=s[i];++j)
            scanf("%d%d",&v[i][j],&w[i][j]);
    }
    for(int i=1;i<=n;++i)
        for(int j=V;j>=0;--j)
            for(int k=1;k<=s[i];++k)
                if(j>=v[i][k])
                    dp[j]=max(dp[j],dp[j-v[i][k]]+w[i][k]);
    printf("%d\n",dp[V]);
    return 0;
}
View Code

 


 

VII. There knapsack problem dependent

Topic link: https: //www.acwing.com/problem/content/description/10/

The meaning of problems: there are n items, backpacks capacity V. Each item has three attributes, the volume, and the value of the parent node. And if selected from a predetermined node, you must choose its parent node.

Ideas: knapsack problem tree, the tree group dp + backpack. DP [u] [j] u represents for the subtree rooted at, the maximum capacity value of j backpack. Suppose v1, v2, v3 subnodes u is 3, then the equivalent of 3 groups, each group select up to a scheme. All obtained by recursive maximum dp [v1] [j], and to v2, v3 empathy. Then transfer equation dp [u] [j] = max (dp [u] [j], dp [u] [jk] + dp [v1] [k]), where 0 <= k <= j, expressed in the total volume of the selected sub-tree v1 to be k.

Note that we chose the child nodes, you must select the current node, then the final location of the parent node of the need to empty out. (All have been considered complete update about the volume, on the inside with the parent node of this article) describes some abstract, Refer to code it.

Complexity of O (nV ^ 2).

AC Code:

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=105;
int n,V,cnt,root,head[maxn],v[maxn],w[maxn],dp[maxn][maxn];

struct node{
    int v,nex;
}edge[maxn];

void adde(int u,int v){
    edge[++cnt].v=v;
    edge[cnt].nex=head[u];
    head[u]=cnt;
}

void dfs(int u){
    for(int i=head[u];i;i=edge[i].nex){
        int v=edge[i].v;
        dfs(v);
        for(int j=V;j>=0;--j)
            for(int k=0;k<=j;++k)
                dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]);
    }
    for(int j=V;j>=0;--j)
        if(j>=v[u]) dp[u][j]=dp[u][j-v[u]]+w[u];
        else dp[u][j]=0;
}

int main(){
    scanf("%d%d",&n,&V);
    for(int i=1;i<=n;++i){
        int u;
        scanf("%d%d%d",&v[i],&w[i],&u);
        if(u==-1) root=i;
        else adde(u,i);
    }
    dfs(root);
    printf("%d\n",dp[root][V]);
    return 0;
}
View Code

 


 

VIII. Knapsack problem several programs seeking

Topic link: https: //www.acwing.com/problem/content/description/11/

Meaning of the questions: Ask maximize the value of the number of programs on the basis of 01 backpack on.

Ideas: Just add an array num [j], j expressed backpack capacity to take optimum solution when the number of programs, num array is initialized to one. Complexity of O (nV).

AC Code:

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=1005;
const int MOD=1e9+7;
int n,V,dp[maxn],num[maxn];

int main(){
    scanf("%d%d",&n,&V);
    for(int i=0;i<=V;++i)
        num[i]=1;
    for(int i=1;i<=n;++i){
        int v,w;
        scanf("%d%d",&v,&w);
        for(int j=V;j>=v;--j){
            if(dp[j]<dp[j-v]+w){
                dp[j]=dp[j-v]+w;
                num[j]=num[j-v];
            }
            else if(dp[j]==dp[j-v]+w){
                num[j]+=num[j-v];
                num[j]%=MOD;
            }
        }
    }
    printf("%d\n",num[V]);
    return 0;
}
View Code

 


 

IX. Knapsack problem seeking specific programs

Topic link: https: //www.acwing.com/problem/content/12/

Meaning of the title: 01 backpack, output lexicographically smallest optimal solution.

Ideas: First, we have from 1 to n items traversing a small number to ensure preference, so as to ensure the lexicographically smallest. Then traverse from 1 to n is determined whether i is selected. Complexity of O (nV).

AC Code:

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=1e3+5;
int n,V,v[maxn],w[maxn],dp[maxn][maxn],ans[maxn];

int main(){
    scanf("%d%d",&n,&V);
    for(int i=1;i<=n;++i)
        scanf("%d%d",&v[i],&w[i]);
    for(int i=n;i>=1;--i)
        for(int j=V;j>=0;--j)
            if(j>=v[i]) dp[i][j]=max(dp[i+1][j],dp[i+1][j-v[i]]+w[i]);
            else dp[i][j]=dp[i+1][j];
    int tmp=V;
    for(int i=1;i<=n;++i)
        if(tmp>=v[i]&&dp[i][tmp]==dp[i+1][tmp-v[i]]+w[i]){
            printf("%d ",i);
            tmp-=v[i];
        }
    printf("\n");
    return 0;
}
View Code

Guess you like

Origin www.cnblogs.com/FrankChen831X/p/11423350.html