1. Title Description: Click to open the link
2. Problem-solving ideas: The subject is a complete knapsack problems of a deformation. According to test instructions, the value of each item varies linearly with a[i], but does not vary linearly with b[i), and B[i] is only counted when the first item of article I is selected, and not at any other time. Therefore, the state here is more than the normal full backpack to add a dimension: whether it is the first time to select the item I, that is, (I,j,flag) indicates whether the current backpack capacity is J, is the first time to select the article I item maximum value. It is not difficult to obtain the following state transfer equations:
DP (i+1,j,0) =MAX{DP (i,j,0), DP (i,j,1)};
DP (i+1,j,1) =MAX{DP (i+1,j-w[i],0) +A[I]+B[I],DP (i+1,j-w[i],1) +a[i]}; (J≥w[i])
The first equation indicates that when the item I is not selected, its maximum value is derived from the maximum value of the first item I purchased. The second equation indicates that when the item I is selected, if Item I is selected for the first time, then it is equal to DP (i+1,j-w[i],0) +a[i]+b[i], if he has been selected, then equal to DP (i+1,j-w[i],1) +a[i]. Take two of the larger one.
3. Code:
#pragma COMMENT (linker, "/stack:1024000000,1024000000") #include <iostream> #include <algorithm># include<cassert> #include <string> #include <sstream> #include <set> #include <bitset># include<vector> #include <stack> #include <map> #include <queue> #include <deque># include<cstdlib> #include <cstdio> #include <cstring> #include <cmath> #include <ctime># Include<cctype> #include <functional>using namespace std; #define ME (s) memset (s,0,sizeof (s)) #define REP (i , n) for (int i=0;i< (n); i++) typedef long LONG ll;typedef unsigned int uint;typedef unsigned long long ull;typedef pair &L T;int, int> p;const int n=2000+10;int dp[n][n][2];int a[n],b[n];int w[n];int main () {int T; For (scanf ("%d", &t); t--;) {int m,n; scanf ("%d%d", &m,&n); for (int i=0;i<n;i++) scanf ("%d%d%d", &w[i],&a[i],&b[i]); Me (DP); for (int. i=0;i<n;i++) for (int j=0;j<=m;j++) {Dp[i+1][j][0]=max (dp[i][j][0],dp[i][j][1]); if (J>=w[i]) Dp[i+1][j][1]=max (Dp[i+1][j-w[i]][0]+a[i]+b[i],dp[i+1][j-w[i]][1]+a[i]); } int Ans=max (dp[n][m][0],dp[n][m][1]); printf ("%d\n", ans); }}
Similarly, this equation can remove the dimension of I and become a two-dimensional array.
#pragma COMMENT (linker, "/stack:1024000000,1024000000") #include <iostream> #include <algorithm># include<cassert> #include <string> #include <sstream> #include <set> #include <bitset># include<vector> #include <stack> #include <map> #include <queue> #include <deque># include<cstdlib> #include <cstdio> #include <cstring> #include <cmath> #include <ctime># Include<cctype> #include <functional>using namespace std; #define ME (s) memset (s,0,sizeof (s)) #define REP (i , n) for (int i=0;i< (n); i++) typedef long LONG ll;typedef unsigned int uint;typedef unsigned long long ull;typedef pair &L T;int, int> p;const int n=2000+10;int dp[n][2];int a[n],b[n];int w[n];int main () {int T; For (scanf ("%d", &t); t--;) {int m,n; scanf ("%d%d", &m,&n); for (int i=0;i<n;i++) scanf ("%d%d%d", &w[i],&a[i],&b[i]); Me (DP); for (int i=0;i<n;i++) foR (int j=0;j<=m;j++) {Dp[j][0]=max (dp[j][0],dp[j][1]); if (J>=w[i]) Dp[j][1]=max (Dp[j-w[i]][0]+a[i]+b[i],dp[j-w[i]][1]+a[i]); } int Ans=max (dp[m][0],dp[m][1]); printf ("%d\n", ans); }}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
HDU 5410 CRB and his Birthday (2015-Year School competition, 10th game)