01背包

0/1背包【基础算法・动态规划】——中高级
Time Limit: 1000MS   Memory Limit: 1000K
Total Submissions: 576   Accepted: 308

Description

一个旅行者有一个最多能装m公斤的背包,现有n件物品,它们的重量分别是w1,w2,w3,...,wn,它们的价值分别为c1,c2,c3,...,cn。若每种物品只有一件,求旅行者能获得的最大总价值。

Input

m,和n(m<=200, n<=30)
接下来共n行每行两个整数wi,ci

Output

最大总价值

Sample Input

10 4 2 1 3 3 4 5 7 9

Sample Output

12
 

列出表格,找规律
v w id 0 1 2 3 4 5 6 7 8 9 10
    0 0 0 0 0 0 0 0 0 0 0 0
2 6 1 0 0 0 0 0 0 2 2 2 2 2
2 3 2 0 0 0 2 2 2 2 2 2 4 4
6 5 3 0 0 0 2 2 6 6 6 8 8 8
5 4 4 0 0 0 2 5 5 5 7 8 11 11
4 6 5 0 0 0 2 5 5 5 7 8 11 11

 

 

 

 

 

 

 

得到如下公式:

\[
dp[i][j]=
\begin{cases}
max\{dp[i-1][j],v_i+dp[i-1][j-w_i]\},\quad \ \ & w_i\leq j,\\
dp[i-1][j], \quad \ \ & j<w_i,
\end{cases}
\]

 


 

AC代码如下:

 1 /*01背包*/ 
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 
 8 int v[35],w[35];
 9 int dp[35][205];
10 
11 int main()
12 {
13     int m,n;
14     scanf("%d%d",&m,&n);
15     for(int i=1;i<=n;i++)
16         scanf("%d%d",&w[i],&v[i]);
17     for(int i=1;i<=n;i++)
18     {
19         if(w[i]>m)
20         {
21             for(int j=1;j<=m;j++)
22                 dp[i][j]=dp[i-1][j];
23             continue;
24         }
25         for(int j=1;j<w[i];j++)
26             dp[i][j]=dp[i-1][j];
27         for(int j=w[i];j<=m;j++)
28             dp[i][j]=max(dp[i-1][j],v[i]+dp[i-1][j-w[i]]);
29     }
30     printf("%d\n",dp[n][m]);
31     return 0;
32 }

 

 

参考:0/1 Knapsack Problem Dynamic Programming

 

posted @ 2017-07-07 18:49  add_oil  阅读(266)  评论(0编辑  收藏  举报