递归
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 5 using namespace std; 6 7 const int max_n = 100+2; 8 9 int dp[max_n][max_n]; 10 int w[max_n],v[max_n]; 11 int n,W; 12 13 int rec(int i,int j) 14 { 15 if(dp[i][j]>=0) 16 { 17 return dp[i][j]; 18 } 19 20 int res; 21 22 if(i==n) 23 { 24 res=0; 25 } 26 else if(j<w[i]) 27 { 28 res=rec(i+1,j); 29 } 30 else 31 { 32 res=max( rec(i+1,j),rec(i+1,j-w[i])+v[i] ); 33 } 34 35 return dp[i][j]=res; 36 } 37 38 int main() 39 { 40 scanf("%d %d",&n,&W); 41 for(int i=0;i<n;++i) 42 { 43 scanf("%d %d",&w[i],&v[i]); 44 } 45 memset(dp,-1,sizeof(dp)); 46 printf("%d ",rec(0,W)); 47 return 0; 48 } 49 50 51 /* 52 4 5 53 2 3 54 1 2 55 3 4 56 2 2 57 */
递推
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 5 using namespace std; 6 7 const int max_n = 100+2; 8 const int max_W = 10000+2; 9 10 int n,W; 11 int dp[max_n][max_W]; 12 // 定义如下: 13 // dp[i][j]:从前i个物品中,选出重量不超过j的物品 14 // dp[0][j]=0 15 // d[i][j]=? 16 // if(j<w[i]) dp[i][j]=dp[i-1][j] 17 // else dp[i][j]=max(dp[i-1][j],dp[i][j-w[i]] + v[i]) 18 int w[max_n],v[max_n]; 19 20 void solve() 21 { 22 memset(dp,-1,sizeof(dp)); 23 // dp[0][j] = 0 24 // 初始条件 25 for(int i=0;i<=n;++i) 26 { 27 dp[0][i]=0; 28 } 29 30 for(int i=1;i<=n;++i) 31 { 32 for(int j=0;j<=W;++j) 33 { 34 if(j<w[i]) 35 { 36 dp[i][j]=dp[i-1][j]; 37 } 38 else 39 { 40 dp[i][j]=max( dp[i-1][j] , dp[i-1][j-w[i]] + v[i] ); 41 } 42 } 43 } 44 } 45 46 int main() 47 { 48 scanf("%d %d",&n,&W); 49 for(int i=1;i<=n;++i) 50 { 51 scanf("%d %d",&w[i],&v[i]); 52 } 53 solve(); 54 printf("%d ",dp[n][W]); 55 return 0; 56 }