01背包问题

参考了http://www.cnblogs.com/qinyg/archive/2012/04/26/2471829.html

 

关键的状态转移方程如下

令V(i,j)表示在前i(1<=i<=n)个物品中能够装入容量为就j(1<=j<=C)的背包中的物品的最大价值,则可以得到如下的动态规划函数:

(1)   V(i,0)=V(0,j)=0 

(2)   V(i,j)=V(i-1,j)  j<wi  

       V(i,j)=max{V(i-1,j) ,V(i-1,j-wi)+vi) } j>wi

(1)式表明:如果第i个物品的重量大于背包的容量,则装人前i个物品得到的最大价值和装入前i-1个物品得到的最大价是相同的,即物品i不能装入背包;第(2)个式子表明:如果第i个物品的重量小于背包的容量,则会有一下两种情况:(a)如果把第i个物品装入背包,则背包物品的价值等于第i-1个物品装入容量位j-wi 的背包中的价值加上第i个物品的价值vi; (b)如果第i个物品没有装入背包,则背包中物品价值就等于把前i-1个物品装入容量为j的背包中所取得的价值。显然,取二者中价值最大的作为把前i个物品装入容量为j的背包中的最优解。

 

 

用poj3624练手

第一次开二维dp数组,直接超内存

第二次用两个一维数组交替,内存是没超,但是耗时400多ms,而且代码比较丑陋

 1 #include <iostream>
 2 #include <string>
 3 #include <sstream>
 4 #include <vector>
 5 
 6 using namespace std;
 7 
 8 
 9 int main()
10 {
11     int n, m;
12     cin >> n >> m;
13     int *w = (int*)malloc(sizeof(int)*(n+1));
14     int *d = (int*)malloc(sizeof(int)*(n + 1));
15 
16     int *dp = (int *)(malloc(sizeof(int)*(m+1)));
17     int *dp_t = (int *)(malloc(sizeof(int)*(m + 1)));
18 
19     memset(dp, 0, sizeof(int)*(m + 1));
20 
21     for (int i = 1; i <= n; i++)
22     {
23         cin >> w[i] >> d[i];
24     }
25 
26     for (int i = 1; i <= n; i++)
27     {
28         memset(dp_t, 0, sizeof(int)*(m + 1));
29 
30         for (int j = 1; j <= m; j++)
31         {
32             int x = dp[j];
33             int y = 0;
34             if(j >= w[i])
35                 y = dp[j - w[i]] + d[i];
36             dp_t[j] = x < y ? y : x;
37             
38         }
39 
40         memcpy(dp, dp_t, sizeof(int)*(m + 1));
41     }
42 
43     cout << dp[m] << endl;
44 
45     //system("pause");
46 }
View Code

看了一下别人的代码,才发现有更优雅的处理方法,修改后代码如下,耗时也缩短为不到300ms

 1 #include <iostream>
 2 #include <string>
 3 #include <sstream>
 4 #include <vector>
 5 
 6 using namespace std;
 7 
 8 int dp[12900];
 9 int w[3410], d[3410];
10 
11 int main()
12 {
13     int n, m;
14     cin >> n >> m;
15 
16     memset(dp, 0, sizeof(dp));
17 
18     for (int i = 1; i <= n; i++)
19     {
20         cin >> w[i] >> d[i];
21     }
22 
23     for (int i = 1; i <= n; i++)
24     {
25 
26         for (int j = m; j > 0; j--)
27         {
28             int x = dp[j];
29             int y = 0;
30             if(j >= w[i])
31                 y = dp[j - w[i]] + d[i];
32             dp[j] = x < y ? y : x;
33         }
34     }
35 
36     cout << dp[m] << endl;
37 
38     //system("pause");
39 }
View Code

 

posted @ 2015-09-19 01:08  qeDVuHG  阅读(376)  评论(0编辑  收藏  举报