• 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
  • 相关阅读:
    Memory Limit Exceeded
    浙江省程序设计竞赛2019
    hdu3974 Assign the task
    TCP面向字节流和UDP面向报文的区别
    django-admin和django-admin.py的区别
    利用 pip 安装 Python 程序包到个人用户文件夹下
    PyCharm中目录directory与包package的区别及相关import详解
    分布式表示(Distributed Representation)
    Nginx
    32.最长有效括号
  • 原文地址:https://www.cnblogs.com/stevenczp/p/4820809.html
Copyright © 2020-2023  润新知