dp- knapsack problem

Knapsack problem template theory

A backpack with a total capacity V, and now there are N goods, the i-th article capacity weight [i], value for value [i], and now to the backpack to hold things, how to dress to make the total value of the backpack items maximum. The main divided into three categories:

  • 01 backpack, each article can take the value 0 or 1.
  • Full backpack, each item can take unlimited number of times.
  • Multiple backpack, each item has a number of limitations, the i-th item can be up NUM [i] a.

Overall, it is divided into a backpack filled just with a backpack filled with no two cases

01 knapsack problem

Have only one of each item, and does not select only select two states
have N items V and a capacity of the backpack, only one of each item can be selected or leave. By weight of the i-th items that w [i], the value is v [i]. Solving the article into the backpack which allows the sum of the weight of these items does not exceed the capacity of the backpack, and the sum of the maximum value.

For any questions there are only two states can be transformed into 01 knapsack problem

DP defined state [i] [v] denotes the front i items placed exactly a maximum capacity value v backpack available.
State transition equation:
dp[i][v]=max(dp[i-1][v], dp[i-1][v-w[i]]+v[i])

`dp[v]=max(dp[v],dp[v-w[i]]+v[i])`

Space complexity O (N W is), or O (W), the time complexity is O (n- W is)

for(int i=0;i<n;i++){
    for(int j=背包大小;j>=w[i];j--){
        dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
    }
}

Analysis:
First, a cycle from 0 to n refers to the n objects
Secondly, the circulation from the backpack size to the weight of the current object, is to reduce the time complexity and so get
for w [i] is the weight of the object, if is smaller than the size of the remaining backpack w [i], and no need to recycle, it is an endpoint w [i]
and j is the current meaning of a total capacity of the backpack, the backpack not be greater than the size of the capacity, so the size of the other in the backpack size
if it is ascending, it will of dp [jw [i]] is operated, it means that, if j is w [i] in multiples, then v [i] will continue to be added, which is completely backpack problem
and for descending, it will ensure that every time the j-th objects can only be placed in 1 this, rather than multiple times, that is 01 backpack

Multiple Knapsack Problem

Each article available at most n pieces
of N kinds of goods and a backpack capacity of V. The i-th item is available at most n pieces, each volume is C, a value of w. Solving the article into the backpack which allows the sum of the volumes of these items does not exceed the capacity of the backpack, and the sum of the maximum value.

For multiple knapsack problem, can be transformed into 01 knapsack problem, such as the two value of 5, a weight of the article 2 to be transformed into two items a and b, a value of 5, a weight of 2, 5 is also a value, 2 is the weight

State transition equation:
dp[i][j]=max(dp[i-1][j],dp[i-1][j-k*w[i]]+k*v[i]) 其中0<=k<=c[i]

`dp[j]=max(dp[j],dp[j-k*w[i]]+k*v[i])`

k is the number of each item put

 for(int i=1;i<=n;i++)
    for(int j=m;j>=0;j--)
        for(int k=1;k<=c[i];k++){
            dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
        }
    }
}

Complete knapsack problem

Each item has an infinite element
there are N kinds of goods and a backpack capacity V, each item has infinite element is available. Volume is the i-th item c, is the value of w. Which allows the article into the backpack sum of the volumes of these items does not exceed the capacity of the backpack, and the sum of the maximum value.

State transition equation:
dp[i][j]=max(dp[i][j],dp[i-1][v-k*w[i]]+k*v[i]) 其中0<=k*w[i]<=背包大小

`dp[j] = max(dp[j], dp[j - w[i]] + v[i]);`

See 01 backpack analysis objects, and 01 backpacks, as is the circulation direction of the inner loop is different, a rise, a fall

Degree hybrid space O (N W is), or O (W), the time complexity is O (N W is)

Code

for (int i = 1; i <= n; i++) {
    for (int j = w[i]; j <= 背包大小; j++) {
        dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
    }
}

Backpack mix

The three kinds of backpacks were mixed, if a maximum of only choose one, some may choose unlimited for some items
the use of 01 backpacks and backpack line of code completely different, judge

for(int i=0;i<n;i++){
    if(第i个物品是01背包){
        for(int j=背包大小;j>=w[i];j--){
            dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
        }
    }else if(第i个物品是完全背包){
        for (int j = w[i]; j <= 背包大小; j++) {
            dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
        }
    }
}

If you add multiple words backpack
backpack mix of pseudo-code

for i= 1 to n
    if 第i件物品属于01背包
        ZeroOnePack(dp,wi,vi)
    else if 第i件物品属于完全背包
        CompletePack(dp,wi,vi)
    else if 第i件物品属于多重背包
        MultiplePack(dp,wi,vi,ni)

Summary template

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int N=1000000;
int v[N],w[N];
int dp[N];
void ZeroOnePack(int i){
    for(int j=背包大小;j>=w[i];j--){
        dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
    }
}
void CompletePack(int i){
    for(int j=w[i];j<=背包大小;j++){
        dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
    }
}
void MultiplePack(int i){
    for(int j=m;j>=0;j--)
        for(int k=1;k<=c[i];k++){
            dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
        }
    }
}
int main(){
    memste(dp,0,sizeof(dp));
    for(int i=0;i<n;i++){
    if(第i个物品是01背包问题){
        ZeroOnePack(i);
    }else if(第i个物品是完全背包问题){
        CompletePack(i);
    }else if(第i个物品是多重背包问题){
        MultiplePack(i);
    }
}

Do title record

first question:

Complete knapsack problem
HUD1248

Problem Description
undead Lich King wages pull, N Death Knight get a dollar bill (remember, only a bill), in order to prevent themselves frequently die in the battle, he decided to buy himself some of the props so he came to the Goblin Merchant.

Death Knight: "I want to buy props!"

Goblin Merchant: "Here we have three props, potions 150 a, 200 a magic drug, potion 350 a invincible."

Death Knight: "Okay, give me a potions."

Then he took out dollar bills handed goes N Goblin Merchant.

Goblin Merchant: "I forgot to remind you, we do not have the habit of looking for the guests money, and more money when we have received a tip, hey."

Death knight:"......"

Death Knight thought it would send a tip money when he himself might as well buy more props, anyway, later to be bought, bought breakfast at home or, as little as possible but to make him earn tips.

Death Knights now want you to help him calculate, how much he will give at least a tip businessman Goblin.

Input
first line of input data is an integer T (1 <= T <= 100), represents the number of test data then is T rows of test data, the test data each containing only a positive integer N (1 <= N < = 10000), N represents the face value of the death knight in the hands of bank notes.

Note: Goblin shops are only three items described in the title.

Output
For each test case, you have to waste a minimum output death knight how much money to the merchant as a fine tip.

Sample Input

2
900
250

Sample Output

0
50

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int w[]={150,200,350};
int v[]={150,200,350};
int dp[10005];
int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        scanf("%d",&n);
        memset(dp,0,sizeof(dp));

        for(int i=0;i<3;i++){
            for(int j=w[i];j<=n;j++){
                dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
            }
        }
        printf("%d\n",n-dp[n]);
    }

    return 0;
}

The second question:

完全背包问题
Problem Description:
Before ACM can do anything, a budget must be prepared and the necessary financial support obtained. The main income for this action comes from Irreversibly Bound Money (IBM). The idea behind is simple. Whenever some ACM member has any small money, he takes all the coins and throws them into a piggy-bank. You know that this process is irreversible, the coins cannot be removed without breaking the pig. After a sufficiently long time, there should be enough cash in the piggy-bank to pay everything that needs to be paid.

But there is a big problem with piggy-banks. It is not possible to determine how much money is inside. So we might break the pig into pieces only to find out that there is not enough money. Clearly, we want to avoid this unpleasant situation. The only possibility is to weigh the piggy-bank and try to guess how many coins are inside. Assume that we are able to determine the weight of the pig exactly and that we know the weights of all coins of a given currency. Then there is some minimum amount of money in the piggy-bank that we can guarantee. Your task is to find out this worst case and determine the minimum amount of cash inside the piggy-bank. We need your help. No more prematurely broken pigs!
Input
The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing two integers E and F. They indicate the weight of an empty pig and of the pig filled with coins. Both weights are given in grams. No pig will weigh more than 10 kg, that means 1 <= E <= F <= 10000. On the second line of each test case, there is an integer number N (1 <= N <= 500) that gives the number of various coins used in the given currency. Following this are exactly N lines, each specifying one coin type. These lines contain two integers each, Pand W (1 <= P <= 50000, 1 <= W <=10000). P is the value of the coin in monetary units, W is it's weight in grams.
Output
Print exactly one line of output for each test case. The line must contain the sentence "The minimum amount of money in the piggy-bank is X." where X is the minimum amount of money that can be achieved using coins with the given total weight. If the weight cannot be reached exactly, print a line "This is impossible.".
Sample Input

3
10 110
2
1 1
30 50

10 110
2
1 1
50 30

1 6
2
10 3
20 4

Sample Output

The minimum amount of money in the piggy-bank is 60.
The minimum amount of money in the piggy-bank is 100.
This is impossible.

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const long long INF=500005,N=10005;
int w[N];
int v[N];
int dp[N];
int main(){
    int t;
    cin>>t;
    while(t--){
        int e,f;
        scanf("%d%d",&e,&f);
        int n;
        cin>>n;
        int W=f-e;
        for(int i=0;i<n;i++){
            scanf("%d%d",&v[i],&w[i]);
        }
        //求最小值,所以对所有的dp进行赋值大数字,但除了第一个数,因为对所有赋值的话,最小值就是大数
        for(int i=1;i<=W;i++){
            dp[i]=INF;
        }

        for(int i=0;i<n;i++){
            for(int j=w[i];j<=W;j++){
                dp[j]=min(dp[j],dp[j-w[i]]+v[i]);
            }
        }

        if(dp[W]==INF){
            printf("This is impossible.\n");
        }else{
            printf("The minimum amount of money in the piggy-bank is %d.\n",dp[W]);
        }

    }

    return 0;
}

Third question:

01 knapsack problem dp probability of
HDU1203
Problem the Description
Speakless long time I wanted to go abroad, and now he has finished all the required exams, prepare all the materials to be prepared, so they need to apply for school. To apply for any university abroad, you have to pay a fee to apply, this is very striking. Speakless not have much money, just to save a total of $ n million. He will select a number of (of course within his affordability range) in the m schools. Each school has a different application fee a (million dollars), and Speakless estimated he got the school offer the possibility of b. Whether the offer will not affect each other between different schools. "I NEED A OFFER", he cried. Help the poor folks, help him calculate that he could receive the maximum probability of at least one offer. (If you selected multiple Speakless school, get a school of any offer can be).

Input
is input several groups of data, each data line of the first two positive integers n-, m (0 <= n-<= 10000,0 <= m <= 10000)
m behind the line, each line has two data ai (integer), bi (real) denote the i-th school application fee and may get the offer of probability.
Finally, there are two 0 inputs.

Output
each corresponding to a data output representing Speakless possible to obtain the maximum probability of at least one offer. He expressed as a percentage, to the nearest decimal place.

Sample Input

10 3
4 0.1
4 0.2
5 0.3
0 0

Sample Output

44.0%

Hint

You should use printf("%%") to print a '%'.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100000+5;
int v[N];
float p[N],dp[N];
int main(){
    int n,m;//背包大小和学校数目
    while(scanf("%d%d",&n,&m),(n+m)!=0){
        for(int i=0;i<m;i++){
            scanf("%d%f",&v[i],&p[i]);
        }

        memset(dp,0,sizeof(dp));

        for(int i=0;i<m;i++){
            for(int j=n;j>=v[i];j--){
                dp[j]=max(dp[j],1-(1-dp[j-v[i]])*(1-p[i]));
            }
        }


        printf("%.1f%%\n",dp[n]*100);

    }
    return 0;
}

Fourth Question: multiple knapsack problem

Multiple knapsack problem HDU2191, this method is time complexity is O (NCV)

Problem Description
Now suppose you have a total capital of n, m and the market kind of rice, each bag of rice is the product, its price range, and can only buy the whole bag.
I ask: Do you use limited funds up to how many kilograms of grain purchase it?

Input
data is first contains a positive integer C, group C expressed test, the first line of each test are two integers n and m (1 <= n <= 100, 1 <= m <= 100), the amount and type of rice represent funds, then the m rows, each row containing three numbers p, h, and c (1 <= p <= 20,1 <= h <= 200,1 <= c <= 20), respectively, the price of the bag, the weight and the number of bags of the bag corresponding to the type of rice.

Output
For each set of test data, weight can output up to buy rice, you can not just assume that all of the funds to buy rice, and the funds you can not finish. The output of each instance per line.

Sample Input
1
8 2
2 100 4
4 100 2

Sample Output
400

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main(){
    int t;
    cin>>t;
    while(t--){

        int n,m;
        scanf("%d%d",&n,&m);

        int w[105],v[105],c[105];
        int dp[205];

        memset(dp,0,sizeof(dp));

        for(int i=0;i<m;i++){
            scanf("%d%d%d",&v[i],&w[i],&c[i]);
        }

        for(int i=0;i<m;i++){
            for(int k=1;k<=c[i];k++){
                for(int j=n;j>=v[i];j--){
                   dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
                }
            }
        }
        printf("%d\n",dp[n]);

    }


    return 0;
}

optimization

Binary Optimized time will not. . .

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
int w[105],v[105],c[105];
int dp[205];//dp[i]指的是购买价值为i的大米时的总重量

//v为当前的价值,w为当前的重量
void zeroonebag(int v,int w){
    for(int j=n;j>=v;j--){
        dp[j]=max(dp[j],dp[j-v]+w);
    }
}
void completebag(int v,int w){
    for(int j=v;j<=n;j++){
        dp[j]=max(dp[j],dp[j-v]+w);
    }
}
void multiple(int v,int w,int c){
    //价值大于拥有的价值,则是完全背包问题
    if(c*v>=n){
        completebag(v,w);
        return;
    }
    
    //01背包
    int k=1;

    while(k<=c){
        zeroonebag(k*v,k*w);
        c=c-k;
        k=k*2;
    }

    zeroonebag(c*v,c*w);

}
int main(){
    int t;
    cin>>t;
    while(t--){


        scanf("%d%d",&n,&m);

        memset(dp,0,sizeof(dp));

        for(int i=0;i<m;i++){
            scanf("%d%d%d",&v[i],&w[i],&c[i]);
        }


        for(int i=0;i<m;i++){
            multiple(v[i],w[i],c[i]);
        }

        printf("%d\n",dp[n]);


    }

    return 0;
}

Guess you like

Origin www.cnblogs.com/Emcikem/p/11333818.html