Extended knapsack problem - multiple backpack full backpack, backpack mixed

This article to https://blog.csdn.net/sinat_40471574/article/details/89740300 basis, before reading this article, should have a look.

Previous article describes the 01 knapsack problem, then I will introduce the expansion issue 01 Backpack: multiple backpack, backpack and completely mixed backpack.

1. Multiple backpack: http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1714

And 01 backpacks compared to multiple backpack just on the basis of more than 01 backpack on a number of items s, then the problem-solving method is very simple, or greater than the number of items stored in an array of items 1 was repeated, either during the item selection when performed s-1 times more than the same items to choose from. Look at the code:

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int n,m,i,j,k;
    int v[505],w[505],s[505],dp[6005];
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++) scanf("%d%d%d",&v[i],&w[i],&s[i]);
    for(i=1;i<=n;i++)
        for(j=1;j<=s[i];j++)        //多进行s[i]-1次判断
            for(k=m;k>=v[i];k--)
                dp[k]=max(dp[k],dp[k-v[i]]+w[i]);
    printf("%d\n",dp[m]);
}
#include <bits/stdc++.h>
using namespace std;
int v[5010],w[5010],dp[10000];
int main()
{
    int n,m,t1,t2,t3;
    cin>>n>>m;
    int p=0;
    for(int i=1;i<=n;i++)
    {
      cin>>t1>>t2>>t3;
      for(int j=1;j<=t3;j++)    //将物品重复存入数组
      {
         v[++p]=t1;
         w[p]=t2;
      }
    }
    for(int i=1;i<=p;i++)
      for(int j=m;j>=v[i];j--)
       dp[j]=max(dp[j],dp[j-v[i]]+w[i]);

    cout<<dp[m]<<endl;

    return 0;
}

In fact, this question codes may be optimized, because in the actual course of the game, the number of items c [i] may be relatively large, very likely time out as described above two methods. Optimization method is the number of items on the binary division. The article 18, can be split into 1,2,4,8,3. Why can it be so divided, because every number can be used to form a unique binary representation, in the above example, you will find 1-15 different combinations can be represented by 1,2,4,8, which naturally Needless to say, while for the remaining binary split that part (ie 3), the number of 15-18 can also be combined with 1,2,4,8 expressed as a combination of all the previous numbers can be represented since 1-15 number, then the back of 15-18 can be represented by (15-3) to 15 + 3 + 3, 16 can be expressed as 13 + 3. Generalized bit is set to a number n, the remaining binary segmentation x, then remove x, the front portion may represent 1 ~ (nx) number, then the number of the back (nx + 1) ~ n may be formed on (nxx) + x ~ (nx) + x to represent. Reasonableness when mounted on the backpack, the backpack we can assume that the article make the maximum value of n to an article to be loaded, then the number of combinations may be divided after the binary represented seen from the above n, then during the playing table, can be n continue to find by selecting the combination. Look at the code: while the statement is part of the split operation.

#include <iostream>

using namespace std;
const int N=1e5+5;
int v[N],w[N],dp[N];//v[n]价值 w[n]重量
int main()
{
    ios::sync_with_stdio(false);
    int n1,v1,x,vi,wi;
    int p=0;
    cin>>n1>>v1;
    for(int i=1;i<=n1;i++)
    {
        cin>>wi>>vi>>x;
        int c=1;
        while(x-c>0)
        {
          x=x-c;
          v[++p]=c*vi;
          w[p]=c*wi;
          c=c*2;

        }
        v[++p]=x*vi;
        w[p]=x*wi;
    }

    for(int i=1;i<=p;i++)
        for(int j=v1;j>=w[i];j--)
    {
       dp[j]=max(dp[j],dp[j-w[i]]+v[i]);

    }



    cout <<dp[v1]<< endl;
    return 0;
}

2. Fully backpack: http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1713

And 01 backpacks and multiple comparison, an unlimited number of items is entirely different backpack. Talked about in the backpack 01, from the backpack maximum capacity during the playing table begins, in order to prevent the result of a front cover generated. The backpack is completely the opposite, playing the course from the table w [i], has been to the maximum capacity of the backpack, because what we want is the greatest value in the case of the backpack expanding capacity, can hold (because the number of items is unlimited Therefore, when the capacity of the backpack may be loaded several extended article of a), this is to be covered. Look at the code:

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int i,j;
    int m,n;
    int dp[205],w[35],c[35];
    memset(dp,0,sizeof(dp));
    scanf("%d%d",&m,&n);
    for(i=1;i<=n;i++) scanf("%d%d",&w[i],&c[i]);
    for(i=1;i<=n;i++)
    {
        for(j=w[i];j<=m;j++)
        {
            dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
        }
    }
    printf("max=%d\n",dp[m]);
}

3. Mixed backpack: http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1715

Hybrid Backpack is multiple backpack and completely backpack combination of friends, when input, built an array to store what the group is entirely backpack or multiple backpack, for multiple backpack part, binary division store, completely backpack partially stored directly, then play when a table full of backpacks and backpacks multiple operating separately can be friends. Look at the code:

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int i,j,p,n2;
    int v,n;
    int x,y,t;
    int w[500],c[500],flag[500],dp[205];
    memset(dp,0,sizeof(dp));
    p=0;
    scanf("%d%d",&v,&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d%d%d",&x,&y,&t);
        if(t==0)
        {
            w[++p]=x;
            c[p]=y;
            flag[p]=0;
        }
        else
        {
            n2=1;
            while(t-n2>0)
            {
                t-=n2;
                w[++p]=n2*x;
                c[p]=n2*y;
                flag[p]=1;
                n2*=2;
            }
            w[++p]=t*x;
            c[p]=t*y;
            flag[p]=1;
        }
    }
    for(i=1;i<=p;i++)
    {
        if(flag[i]==0)
        {
            for(j=w[i];j<=v;j++)
            dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
        }
        else
        {
            for(j=v;j>=w[i];j--)
            dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
        }
    }
    printf("%d\n",dp[v]);
}

4. Finally, look at two extensions questions:

Sakura: http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1718

Like a mixed bag, but it is worth mentioning that the method of calculation of the number of minutes, remember do not understand when it comes with a variety if written.

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int t[N],c[N],flag[N],dp[N];
int main()
{
    int i,j;
    int h1,m1,h2,m2,n;
    int x,y,tmp;
    int p,v;
    memset(dp,0,sizeof(dp));
    p=0;
    scanf("%d:%d%d:%d%d",&h1,&m1,&h2,&m2,&n);
    v=(h2-h1)*60+(m2-m1);
    for(i=1;i<=n;i++)
    {
        scanf("%d%d%d",&x,&y,&tmp);
        if(tmp==0)
        {
            t[++p]=x;
            c[p]=y;
            flag[p]=0;
        }
        else
        {
            int n2=1;
            while(tmp-n2>0)
            {
                t[++p]=x*n2;
                c[p]=y*n2;
                flag[p]=1;
                tmp-=n2;
                n2*=2;
            }
            t[++p]=tmp*x;
            c[p]=tmp*y;
            flag[p]=1;
        }
    }
    for(i=1;i<=p;i++)
    {
        if(flag[i]==0)
            for(j=t[i];j<=v;j++)
                dp[j]=max(dp[j],dp[j-t[i]]+c[i]);
        else
            for(j=v;j>=t[i];j--)
                dp[j]=max(dp[j],dp[j-t[i]]+c[i]);
    }
    printf("%d\n",dp[v]);
}

Buy hay: http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1711

This question is more unusual, and completely backpack, but to a minimum. Because it is to buy at least h-pound bales of hay, it is possible to buy some hay bales, total weight exceeds h pounds, but spending becomes small, and therefore dp [h] may not be the answer. Because the weight of the individual hay bales is 5000 or less, so we can h + 5000.

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int i,j;
    int n,h;
    int p[105],c[105],dp[55005];
    scanf("%d%d",&n,&h);
    for(i=1;i<=h+5000;i++) dp[i]=0x3f3f3f;
    for(i=1;i<=n;i++)
        scanf("%d%d",&p[i],&c[i]);
    for(i=1;i<=n;i++)
    {
        for(j=p[i];j<=h+5000;j++)
            dp[j]=min(dp[j],dp[j-p[i]]+c[i]);
    }
    int minn=0x3f3f3f;
    for(i=h;i<=h+5000;i++) minn=min(minn,dp[i]);
    printf("%d\n",minn);
}

 

Published 34 original articles · won praise 26 · views 10000 +

Guess you like

Origin blog.csdn.net/sinat_40471574/article/details/89742551