HDU 2602 dynamic programming + two dimensional array and one dimensional array two solutions (01 knapsack)

Keywords: Programming

This problem is a simple dynamic programming when it is solved simply by two-dimensional array, but there may be a case where the volume of pit is 0 but the value is not 0

 

1: Two dimensional array

Here is the error code

#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdio> 
using namespace std;
#define maxn 1001
int T,N,V,
	w[maxn],v[maxn];
int result[maxn][maxn];

void slove()
{
	int i,j;
	for(i=1;i<=N;i++){
		for(j=1;j<=V;j++){
			if(j>=w[i]){
				result[i][j]=max(result[i-1][j],result[i-1][j-w[i]]+v[i]);
			}else{
				result[i][j]=result[i-1][j];
			}
		}
	}
}

int main()
{
	cin >> T;
	while(T--)
	{
		memset(result,0,sizeof(result));
		cin >> N >> V;
		int i,j;
		for(i=1;i<=N;i++){
			scanf("%d",&v[i]);
		}
		for(i=1;i<=N;i++){
			scanf("%d",&w[i]);
		}
		slove();
		cout << result[N][V] << endl;
	}
	
	return 0;
}

This is an example I tested at that time:

1

3 10

1 2 3

0 5 0

Why is the output 5 instead of 6? The quality of the first item from result[1][1] to result[1][10]. When traversing to the second item, result [i] [J] = max (result [I-1] [J], result [I-1] [J-W [i]] + v [i]). Since v[1][0] is 0 or not 1, the value of the first item is not added at this time

Solution: j=0, then traverse

#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdio> 
using namespace std;
#define maxn 1001
int T,N,V,
	w[maxn],v[maxn];
int result[maxn][maxn];

void slove()
{
	int i,j;
	for(i=1;i<=N;i++){
		for(j=0;j<=V;j++){//If you let j=1 start traversal, there will be an error!!! (there will be a case where the value is not 0, but the volume is 0) 
			if(j>=w[i]){
				result[i][j]=max(result[i-1][j],result[i-1][j-w[i]]+v[i]);
			}else{
				result[i][j]=result[i-1][j];
			}
		}
	}
}

int main()
{
	cin >> T;
	while(T--)
	{
		memset(result,0,sizeof(result));
		cin >> N >> V;
		int i,j;
		for(i=1;i<=N;i++){
			scanf("%d",&v[i]);
		}
		for(i=1;i<=N;i++){
			scanf("%d",&w[i]);
		}
		slove();
		cout << result[N][V] << endl;
	}
	
	return 0;
}

 

2: One dimensional array:

The solution of one-dimensional array is compression in two-dimensional array space:
When the two-dimensional array traverses the table printing, the first row is from result[1][0] to result[1][V], and then the second row begins. In this way, why not type the table directly on the basis of the first row?

My own mistakes:

Just touching dynamic planning, when two-dimensional changes into one-dimensional, the direction of thinking is always V as the outer circle, and then traverse the input data many times, then a mark is needed. So I defined the visited array to record whether the backpack has been selected. But the problem is that when the backpack is chosen and then lost, the mark is not easy to return. Then I began to think of various ways to get rid of markers....

#include <iostream>
#include <cstdio> 
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 10001

int N,V;
int w[maxn],v[maxn];
int dp[maxn];//What is recorded is the maximum value that the current maximum capacity can obtain 

void slove()
{
	int i,j;
	for(i=1;i<=N;i++){
		for(j=V;j>=w[i];j--){
			dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
		}
	}
}

int main()
{
	
	int T;
	cin >> T;
	while(T--)
	{
		memset(dp,0,sizeof(dp));
		cin >> N >> V;
		int i;
		for(i=1;i<=N;i++){
			scanf("%d",&v[i]);
		}	
		for(i=1;i<=N;i++){
			scanf("%d",&w[i]);
		}
		slove();
		cout << dp[V] << endl;
	} 
	return 0;
}

 

Posted by po on Thu, 19 Dec 2019 08:01:50 -0800