(Acwing) Complete Knapsack Problem

There are N items and a knapsack of capacity V, and infinite pieces of each item are available.

Item ii has volume vi and value wi.

Solve which items to put into the backpack so that the total volume of these items does not exceed the capacity of the backpack and the total value is the largest.
output the maximum value.

input format

In the first line, two integers, N and V, are separated by spaces, which represent the number of items and the volume of the backpack respectively.

Next there are N lines, each line has two integers vi, wi, separated by spaces, representing the volume and value of the i-th item respectively.

output format

Output an integer representing the maximum value.

data range

0<N,V≤1000
0<vi,wi≤1000

input sample

4 5
1 2
2 4
3 4
4 5

Sample output: 

10

Simple writing: it will time out 

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1010;
int n,m;
int v[N],w[N];
int f[N][N];

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>v[i]>>w[i];
    
    for(int i=1;i<=n;i++)
       for(int j=0;j<=m;j++)
          for(int k=0;k*v[i]<=j;k++)
             f[i][j] = max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);
              
    cout<<f[n][m]<<endl;
}

 Divide by how many items:

 

Perform a two-dimensional optimization:

#include<iostream>
#include<algorithm>
using namespace std;
 
const int N = 1010;
int n,m;     
int v[N],w[N]; 
int f[N][N];   
 
int main()
{
    cin>>n>>m;
    
    for(int i=1;i<=n;i++) cin>>v[i]>>w[i];
    
    for(int i=1;i<=n;i++){
        for(int j=0;j<=m;j++){
            f[i][j] = f[i-1][j];  
            if(j>=v[i]) f[i][j] = max(f[i][j],f[i][j-v[i]]+w[i]);
        }
    }
    
    /*for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            cout<<f[i][j]<<" ";
        }
        cout<<endl;
    }*/
    
    cout<<f[n][m]<<endl;
}

Perform a one-dimensional optimization:

#include<iostream>
#include<algorithm>
using namespace std;
 
const int N = 1010;
int n,m;     
int v[N],w[N]; 
int f[N];   
 
int main()
{
    cin>>n>>m;
    
    for(int i=1;i<=n;i++) cin>>v[i]>>w[i];
    
    for(int i=1;i<=n;i++){
        for(int j=v[i];j<=m;j++){
            //与01背包不同的是,j循环必须从小到大,01背包从大到小是避免覆盖,而这完全背包从小到大是为了必须覆盖
            //由图可知,我们需要实现的是累加的过程
            f[j] = max(f[j],f[j-v[i]]+w[i]);
        }
    }
    
    /*for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            cout<<f[i][j]<<" ";
        }
        cout<<endl;
    }*/
    
    cout<<f[m]<<endl;
}

Guess you like

Origin blog.csdn.net/GF0919/article/details/132061612