# "Algorithm" Backpack Nine talk

Source: Internet
Author: User

Backpack Nine Talk Board

Examples refer to "Information Science Orsay a pass"

Initialization is divided into two cases
1, if the backpack requirements just fill the initialization f[0] = 0, f[1~v] =-inf;
2, if do not need just fill f[0~v] = 0;

01 Backpack

There are n items and a backpack with a capacity of V. The cost of item I (i.e. volume, hereinafter) is w[i], the value is c[i]. The solution of which items are loaded into the backpack allows the sum of the costs of these items to be no more than the backpack capacity and the maximum value.

Examples
"Problem description"
A traveler has a backpack with a maximum of M kg, and now has n items, the weight of which is w1,w2,...,wn, and their value is C1,C2,..., Cn. If there is only one item for each object, the maximum total value can be obtained by the traveler.
"Input Format"
First line: Two integers, M (backpack capacity, m<=200) and N (number of items, n<=30);
2nd.. N+1 line: Two integer wi,ci per line, indicating the weight and value of each item.
"Output Format"
A single row, a number, representing the maximum total value.
"Sample Input" package.in
10 4
2 1
3 3
4 5
7 9
"Sample Output" Package.out
12

• Code

Solution One

``#include<cstdio>using namespace std;const int maxn=201,maxn=31;int m,n;int w[maxn],c[maxn];int f[maxn][maxm]; int max(int x,int y)  { x>y?x:y;}                     //求x和y最大值int main(){    scanf("%d%d",&m,&n);         //背包容量m和物品数量n    for (int i=1;i<=n;i++)         //在初始化循环变量部分，定义一个变量并初始化    scanf("%d%d",&w[i],&c[i]);    //每个物品的重量和价值    for(int i=1;i<=n;i++)         // f[i][v]表示前i件物品，总重量不超过v的最优价值    for(int v=m;v>0;v--)    if(w[i]<=v)      f[i][v]=max(f[i-1][v],f[i-1][v-w[i]]+c[i]);    else    f[i][v]=f[i-1][v];    printf("%d",f[n][m]);           // f[n][m]为最优解    return 0;}``

Solution Two

``#include<cstdio>using namespace std;const int maxm=2001,maxn=31;int m,n;int w[maxn],c[maxn];int f[maxm]; int main(){    scanf("%d%d",&m,&n);            //背包容量m和物品数量n    for (int i=1;i<=n;i++)    scanf("%d%d",&w[i],&c[i]);     //每个物品的重量和价值    for(int i=1;i<=n;i++)             //设f(v)表示重量不超过v公斤的最大价值    for(int v=m;v>=w[i];v--)    if(f[v-w[i]]+c[i]>f[v])    f[v]=f[v-w[i]]+c[i];    printf("%d",f[m]);                      // f(m)为最优解    return 0;}``
Full backpack

There are n items and a backpack with a capacity of V, with unlimited pieces available for each item. The cost of item I is w[i] and the value is c[i]. The solution of which items are loaded into the backpack allows the sum of the costs of these items to be no more than the backpack capacity and the maximum value.

• Examples
"problem description"
has n items, each of which has a weight and a value. But the number of each item is unlimited, at the same time there is a backpack, the maximum load of M, today from n items select several pieces (the same item can be selected multiple times), so that its weight and less than equal to M, and the value of the maximum.
Input Format
The first line: two integers, M (backpack capacity, m<=200) and N (number of items, n<=30);
2nd. N+1 line: Two integer wi,ci per line, indicating the weight and value of each item. The
Output format
is a single row, a number that represents the maximum total value.
Sample Input Knapsack.in
4
2 1
3 3
4 5
7 9
"Sample Output" Knapsack.out
max=12

• Code
Solution /p>

``#include<cstdio>using namespace std;const int maxm=201,maxn=31;int m, n;int w[maxn],c[maxn];int f[maxn][maxm]; int main(){    scanf("%d%d",&m,&n);            //背包容量m和物品数量n    for(int i=1;i<=n;i++)     scanf("%d%d",&w[i],&c[i]);    //每个物品的重量和价值    for(int i=1;i<=n;i++)            //f[i][v]表示前i件物品，总重量不超过v的最优价值    for(int v=1;v<=m;v++)    if(v < w[i])      f[i][v]=f[i-1][v];    else　　if(f[i-1][v]>f[i][v-w[i]]+c[i])    f[i][v]=f[i-1][v];    else     f[i][v]=f[i][v-w[i]]+c[i];     printf("max=%d",f[n][m]);         // f[n][m]为最优解    return 0;}``

Solution Two

``#include<cstdio>using namespace std;const int maxm=2001,maxn=31;int n,m,v,i;int c[maxn],w[maxn];int f[maxm];int main(){    scanf("%d%d",&m,&n);            //背包容量m和物品数量n    for(i=1;i<=n;i++)     scanf("%d%d",&w[i],&c[i]);    for(i=1;i<=n;i++)    for(v=w[i];v<=m;v++)          //设 f[v]表示重量不超过v公斤的最大价值    if(f[v-w[i]]+c[i]>f[v])    f[v]=f[v-w[i]]+c[i];    printf("max=%d\n",f[m]);           // f[m]为最优解    return 0;}``
Multiple backpack

There are n kinds of goods and a backpack with a capacity of V. (i) Items with a maximum of n[i] pieces available, each cost is w[i], the value is c[i]. The solution of which items are loaded into the backpack allows the sum of the costs of these items to be no more than the backpack capacity and the maximum value.

• Examples
Celebration meeting
"Problem description"
In order to celebrate the class in the school sports meeting to obtain the first grade, the head teacher decided to open a celebration meeting, for this grant to buy prizes reward athletes. Expect the amount of money to buy prizes of the greatest value that can replenish their energy and stamina.
"Input Format"
The first line is two number n (n<=500), M (m<=6000), where n represents the number of prizes to be purchased, and M represents the amount of the grant.
The next n lines, 3 numbers per line, V, W, S, respectively, indicate the price, value (price and value of the different concepts) and the quantity purchased (buy 0 to s pieces), where v<=100,w<=1000,s<=10.
"Output Format"
The first line: A number, indicating the maximum value this purchase can get (note!) Not the price).
"Input Sample"
5 1000
80 20 4
40 50 9
30 50 7
40 30 6
20 20 1
"Output Example"
1040
• Code
Solution One
``#include<iostream>using namespace std;int n,m;int f[6002];int v[6002],w[6002],s[6002];int main(){    cin>>n>>m;    for(int i=1;i<=n;i++)    cin>>v[i]>>w[i]>>s[i];    for(int i=1;i<=n;i++)    for(int j=m;j>=0;j--)    for(int k=0;k<=s[i];k++)    {        if(j-k*v[i]<0)        break;        f[j]=max(f[j],f[j-k*v[i]]+k*w[i]);    }    cout<<f[m];}``

Solution two (binary optimization)

``#include<iostream>using namespace std;int n,m;int f[6002];int v[6002],w[6002];int v1,w1,s;int n1=0;int main(){    cin>>n>>m;    while(n--)//把每种划分成不同种类的     {        cin>>v1>>w1>>s;        for(int i=1;i<=s;i*=2)//二进制分解         //把14分成1,2,4,6多出1在后面打包         {            v[++n1]=i*v1;            w[n1]=i*w1;            s-=i;        }        if(s>0)//多出来的一起打包         {            v[++n1]=s*v1;            w[n1]=s*w1;        }    }    for(int i=1;i<=n1;i++)    for(int j=m;j>=v[i];j--)    {        f[j]=max(f[j],f[j-v[i]]+w[i]);    }    cout<<f[m];}``
Mixed backpack

Mix 01 Backpacks, a full backpack, and multiple backpacks. That is, some items can only be taken once (01 backpack), some items can be taken unlimited (full backpack), and some items can be taken the number of times there is an upper limit (multiple backpack).

• Example
"problem description"
A traveler has a backpack with a maximum of v kilograms, and now has n items, the weights of which are w1,w2,...,wn respectively, and their value is C1,C2,..., Cn. Some items can only be taken once (01 backpack), some items can take unlimited (full backpack), some items can be taken in the number of times there is an upper limit (multiple backpack). The solution of which items are loaded into the backpack allows the sum of the costs of these items to be no more than the backpack capacity and the maximum value.
Input Format
The first line: two integers, V (backpack capacity, v<=200), N (number of items, n<=30);
2nd. N+1 Line: three integers per line wi,ci,pi, the first two integers represent the weight of each item, the value, and the third integer if 0, means that the item can be purchased without a number of pieces, if other numbers, the maximum number of pieces (Pi) can be purchased for this item. The
Output format
is a single row, a number that represents the maximum total value.
Sample Input Mix.in
4
2 1 0
3 3 1
4 5 4
Sample output mix.out
One
"Sample explanation"
Select the first item 1 pieces and the third item 2 pieces.
• Code
``#include<cstdio>using namespace std;int m,n;int w[31],c[31],p[31];int f[201];int max(int x,int y){      return    x>y?x:y; }int main(){    scanf("%d%d",&m,&n);    for(int i=1;i<=n;i++)    scanf("%d%d%d",&w[i],&c[i],&p[i]);    for(int i=1;i<=n;i++)    if(p[i]==0)    {                                   //完全背包        for(int j=w[i];j<=m;j++)        f[j]=max(f[j],f[j-w[i]]+c[i]);    }    else    {        for(int j=1;j<=p[i];j++)           //01背包和多重背包        for(int k=m;k>=w[i];k--)        f[k]=max(f[k],f[k-w[i]]+c[i]);    }    printf("%d",f[m]);     return 0;}``
Two-dimensional cost backpack

Two-dimensional knapsack problem refers to: For each item, there are different costs; Select this item must pay both costs; there is a maximum value (backpack capacity) that can be paid for each price. Ask how you choose items to get the most value. The two costs are set at the cost of 1 and the cost of 2 respectively, and the two costs required for article I items are a[i] and b[i]. The maximum value that can be paid for the two costs (two pack sizes) is V and U respectively. The value of the item is c[i].

• Example
"problem description"
Divers use special equipment for diving. He has a cylinder with 2 gases: one for oxygen and one for nitrogen. Allowing divers to dive deeper requires a variety of oxygen and nitrogen. Divers have a certain number of cylinders. Each cylinder has a weight and gas capacity. Divers need a certain amount of oxygen and nitrogen in order to complete his work. What is the minimum amount of the total weight of the cylinder he needs to complete his work?
For example: Divers have 5 cylinders. Three digits per line: oxygen, nitrogen (liter) and cylinder weight:
3 129
,
5,
1,
4, 119
If the diver needs 5 liters of oxygen and 60 liters of nitrogen, the total weight is a minimum of 249 (1, 2 or 4, No. 5th cylinder).
your task is to calculate the minimum value of the cylinder weight that the diver needs to complete his work. The first line of
input format
has 2 integer m,n (1<=m<=21,1<=n<=79). They represent the amount of oxygen and nitrogen that each needs. The
second behavior, integer k (1<=n<=1000), indicates the number of cylinders.
Subsequent K-lines, each containing Ai,bi,ci (1<=ai<=21,1<=bi<=79,1<=ci<=800) 3 integers. These are: the capacity of oxygen and nitrogen in the first cylinder and the weight of the cylinders. The
Output format
line contains only one integer, the lowest value of the total weight of the cylinders required for the diver to complete the work.
• Code
``#include<cstdio>#include<cstring>                                   //初始化memset要用到using namespace std;int v,u,k;int a[1001],b[1001],c[1001];int f[101][101];int main(){    memset(f,127,sizeof(f));                    //初始化为一个很大的正整数    f[0][0]=0;    scanf("%d%d%d",&v,&u,&k);    for(int i=1;i<=k;i++)    scanf("%d%d%d",&a[i],&b[i],&c[i]);    for(int i=1;i<=k;i++)    for(int j=v;j>=0;j--)    for(int l=u;l>=0;l--)    {       int t1=j+a[i],t2=l+b[i];       if(t1>v)         t1=v;                        //若氮、氧含量超过需求，可直接用需求量代换，       if(t2>u)         t2=u;                        //不影响最优解       if(f[t1][t2]>f[j][l]+c[i])       f[t1][t2]=f[j][l]+c[i];    }    printf("%d",f[v][u]);    return 0;}``
Group Backpack

There are n items and a backpack with a capacity of V. The cost of article I is w[i], the value is c[i]. These items are divided into groups in which the items in each group clash with each other, with a maximum of one item selected. The solution of which items are loaded into the backpack allows the sum of the costs of these items to be no more than the backpack capacity and the maximum value.

• Examples
"problem description"
A traveler has a backpack with a maximum of v kilograms, and now has n items, the weights of which are w1,w2,...,wn respectively, and their value is C1,C2,..., Cn. These items are divided into groups in which the items in each group clash with each other, with a maximum of one item selected. The solution of which items are loaded into the backpack allows the sum of the costs of these items to be no more than the backpack capacity and the maximum value.
Input Format
The first line: three integers, V (backpack capacity, v<=200), N (number of items, n<=30) and T (maximum group number, t<=10);
2nd. N+1 line: Three integer wi,ci,p per line, indicating the weight, value, and group number of each item. The
Output format
is a single row, a number that represents the maximum total value.
Sample Input group.in
6 3
2 1 1
3 3 1
4 8 2
6 9 2
2 8 3
3 9 3
"Sample Output" Group.out

• Code

``#include<cstdio>using namespace std;int v,n,t;int w[31],c[31];int a[11][32],f[201];int main(){    scanf("%d%d%d",&v,&n,&t);    for(int i=1;i<=n;i++)    {　　    int p;        scanf("%d%d%d",&w[i],&c[i],&p);        a[p][++a[p][0]]=i;    }    for(int k=1;k<=t;k++)    for(int j=v;j>=0;j--)    for(int i=1;i<=a[k][0];i++)    if (j >= w[a[k][i]])     {        int tmp=a[k][i];        if(f[j]<f[j-w[tmp]]+c[tmp])        f[j]=f[j-w[tmp]]+c[tmp];     }    printf("%d",f[v]);    return 0;}``
A backpack that depends on

There is some kind of "dependency" between the items in this knapsack problem. That is, I relies on j, indicating that if you select item I, you must select item J. For the sake of simplification, we first set up no item that depends on something else and is dependent on something else, and no item is dependent on more than one item at a time.
The problem was extended by NOIP2006 's budget proposal. In accordance with the wording of the question, items that do not depend on other items are referred to as "main pieces", and items that depend on the main part are referred to as "attachments". The simplified condition of this problem shows that all items consist of several main pieces and a collection of attachments that depend on each main piece.

Ideas
1. Divide each attachment into the same group as the main part first
2. Make each group A 01 backpack (Be sure to select the main part)
3. To Group A backpack
• Example
https://www.luogu.org/problemnew/show/P1064

• Code

``#include <iostream>using namespace Std;int n,m;int v[80],p[80],q[80];int s[40400],t[40400];//s Array Save final answer T array save transition answer    int main () {cin>>n>>m;        for (int i=1;i<=m;i++) {cin>>v[i]>>p[i]>>q[i]; p[i]=v[i]*p[i];//first to calculate the cost} for (int i=1;i<=m;i++) {if (q[i]==0) {for (int j=1;j<=v[i ];j++) t[j]=0;//than v[i] small answer can not be assigned to 0 for (int j=v[i];j<=n;j++) {t[j]=s[j- v[i]]+p[i];//Modify the answer larger than V[i]} for (int j=1;j<=m;j++)//Find the attachment {if (q[j]==i                     )//Find the attachment of I {for (int k=n;k>=v[i]+v[j];k--)//must take the main part so K>=v[i]+v[j] (group backpack Idea)                {T[k]=max (t[k],t[k-v[j]]+p[j]);//01 Backpack pack each group}}             for (int k=v[i];k<=n;k++) if (t[k]>s[k]) s[k]=t[k];//Replace with a new answer that is larger than the original answer }}} cout<<s[n];} ``
Total number of scenarios for knapsack problem

For a knapsack problem given the knapsack capacity, the cost of goods, the relationship between items (grouping, dependence, etc.), in addition to the maximum value that can be obtained after the value of each item is given, you can also get the total number of packages filled with backpacks or packaged back to a specified capacity.
For this kind of change to ask the question, generally only need to change the state transition equation max to sum. For example, if each item is an item in a 01 backpack, the transfer equation is f[i][v]=sum{f[i-1][v],f[i-1][v-w[i]]+c[i]} and the initial condition is f[0][0]=1.
In fact, the reason for this is that the state transition equation has examined all possible knapsack composition schemes.

• Examples

"Problem description"
Give you a currency system of n denominations, and find out how many options to make up a currency with a denomination of M. Example: Set n=3,m=10, require input and output in the following format:
"Sample Input" money.in
3 10//3 denomination with a par value of 10 scheme
1//Face value 1
2//Face value 2
5//Face value 5
"Sample Output" Money.out
10//There are 10 kinds of programs

• Code
``#include<cstdio>int m,n;int a[1001];long long f[10001];                     //注意要用long long int main(){    scanf("%d%d",&n,&m);              //n种面值的货币，组成面值为m    for(int i=1;i<=n;i++)    scanf("%d",&a[i]);               //输入每一种面值    f[0]=1;    for(int i=1;i<=n;i++)    for(int j=m;j>=a[i];j--)         //f[j]表示面值为j的总方案数    for(int k=1;k<=j/a[i];k++)    f[j]+=f[j-k*a[i]];    printf("%lld",f[m]);                 // f[m]为最优解    return 0;}``
A wave of blind summary

Overall knapsack problem is not difficult to understand
Mainly the flexibility of the topic need to consider what kind of backpack to use
and the code for each backpack is basically similar.
But there are individual differences.
So to figure out the definition of each variable
It's best to memorize the code and not want to go.

"Algorithm" Backpack Nine talk

Related Keywords:

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

## A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

• #### Sales Support

1 on 1 presale consultation

• #### After-Sales Support

24/7 Technical Support 6 Free Tickets per Quarter Faster Response

• Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.