zoukankan      html  css  js  c++  java
  • 0-1背包问题

    真的好难 


    描述

    Bessie has gone to the mall's jewelry store and spies a charm bracelet. Of course, she'd like to fill it with the best charms possible from the N(1 ≤ N≤ 3,402) available charms. Each charm iin the supplied list has a weight Wi(1 ≤ Wi≤ 400), a 'desirability' factor Di(1 ≤ Di≤ 100), and can be used at most once. Bessie can only support a charm bracelet whose weight is no more than M(1 ≤ M≤ 12,880).

    Given that weight limit as a constraint and a list of the charms with their weights and desirability rating, deduce the maximum possible sum of ratings.


    输入
    Line 1: Two space-separated integers: N and M
    Lines 2..N+1: Line i+1 describes charm i with two space-separated integers: Wi and Di
    输出
    Line 1: A single integer that is the greatest sum of charm desirabilities that can be achieved given the weight constraints
    样例输入
    4 6
    1 4
    2 6
    3 12
    2 7
    样例输出
    23
    来源
    USACO 2007 December Silver


    按照正确的思路写了好长时间,最后一直得不到正确的结果,可能是状态转移方程没有理解清楚,而且还涉及到空间优化的问题(人人为我)

    状态转移方程真的不太好理解,方程一直在变根本就找不到它确切的值。这里先贴上别人的AC代码,以后方便查找


    学0-1背包前要看的一道题

    点击打开链接(神奇的口袋)


    关于0-1背包的讲解

    点击打开链接

    点击打开链接


    空间可以优化

    1
    #include<iostream>  
    2
    #include<fstream> 
    3
    #include<string.h> 
    4
      
    5
    using namespace std;  
    6
      
    7
    static const int N = 3403;  
    8
    static const int M = 12881;  
    9
    static int f[N][M];  		//表示在前N个物品中取重量不超过M的最佳价值
    10
    static int c[N], v[N];  
    11
      
    12
    int main()  
    13
    {  
    14
        int n, m;  			//n是物品的数量,m是背包的总容量
    15
        while (cin >> n >> m)  
    16
        {  
    17
            int i, j;  
    18
            for (i = 1; i <= n; i++)  
    19
            {  
    20
                cin >> c[i] >> v[i];  //c[i]重量	v[i]价值
    21
            }  
    22
            memset(f, 0, sizeof(f));  
    23
            for (i = 1; i <= n; i++)  
    24
            {  
    25
                for (j = 1; j < c[i]; j++)  //背包容量小于物体重量 ->不放
    26
                    f[i][j] = f[i - 1][j];  //价值与上一个状态的价值一样
    27
                for(j = c[i]; j <= m; j++) 
    28
                {  
    29
                    if (f[i - 1][j] < f[i - 1][j - c[i]] + v[i])  	//i和j参数的变化控制状态变化
    30
                        f[i][j] = f[i - 1][j - c[i]] + v[i];  
    31
                    else  
    32
                        f[i][j] = f[i - 1][j]; 
    33
                }  
    34
            }  
    35
            cout << f[n][m] << "
    ";  
    36
        }  
    37
      
    38
        return 0;  
    39
    }

    空间优化后的代码


    1
    #include<iostream>
    2
    #include<string.h>
    3
    #define M 12881
    4
    #define N 3403
    5
    6
    using namespace std;
    7
    8
    int f[M];
    9
    int w[N],v[N];
    10
    11
    int main()
    12
    {
    13
        int n,m;
    14
        cin>>n>>m;
    15
        for(int k=1; k<=n; k++)
    16
        {
    17
            cin>>w[k]>>v[k];
    18
        }
    19
    20
        memset(f, 0, sizeof(f)); 
    21
        for(int i=1; i<=n; i++)
    22
        {
    23
            for(int j=m; j>=w[i]; j--)
    24
            {
    25
                if(f[j]<f[j-w[i]]+v[i])
    26
                    f[j]=f[j-w[i]]+v[i];
    27
            }
    28
        }
    29
        
    30
        cout<<f[m]<<"
    ";
    31
        
    32
        return 0;
    33
    }


    代码虐我千百遍,我待代码如初恋。





    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    python文件压缩示例(压缩当前目录)
    C#实现Socket聊天室
    使用微软企业库5.0进行WCF服务边界上的异常保护
    使用python的内置ctypes模块与c、c++写的dll进行交互
    Python使用tkinter库创建图形界面HelloWorld
    手动处理Team Foundation Server 2010 数据仓库和分析服务数据库
    Linux mmap
    iwconfig linux 命令行配置无线网卡
    Qt中文乱码,设置字符集
    Flex 宋体、黑体、楷体、仿宋字体样式
  • 原文地址:https://www.cnblogs.com/h-hkai/p/7406484.html
Copyright © 2011-2022 走看看