• 南阳oj 860又见01背包


    又见01背包

    时间限制:1000 ms  |  内存限制:65535 KB
    难度:3
    描述
        有n个重量和价值分别为wi 和 vi 的 物品,从这些物品中选择总重量不超过 W 
    的物品,求所有挑选方案中物品价值总和的最大值。
      1 <= n <=100
      1 <= wi <= 10^7
      1 <= vi <= 100
      1 <= W <= 10^9
    输入
    多组测试数据。
    每组测试数据第一行输入,n 和 W ,接下来有n行,每行输入两个数,代表第i个物品的wi 和 vi。
    输出
    满足题意的最大价值,每组测试数据占一行。
    样例输入
    4 5
    2 3
    1 2
    3 4
    2 2
    样例输出
    7


    这道题第一眼看上去没什么特别的,,是啊 ,果断01背包写,当真WA...大哭,,后来仔细读题发现重量的范围高达1e9, 显然这么大是开不了数组的。。。苦思半天无果,看了一篇题解之后恍然大悟,自己的01背包基础太差了,这道题目只需要把价值和重量翻转,改用较小(<=100)的价值来开数组,那么最后求的就是指定价值下的最小重量(仔细想想吧微笑,AC代码如下


    <span style="font-size:18px;">#include<cstdio>
    #include<cstring>
    #include <iostream>
    using namespace std ;
    const int MAXN = 1e9 ;
    
    int w[105],v[105] ;
    int dp[100000] ;
    int n,W ;
    
    int main()
    {
        while(scanf("%d%d",&n,&W)!=EOF)
        {
            int sum = 0 ;   //总价值
            for(int i = 0 ;i<n ;i++)
            {
                scanf("%d%d",&w[i],&v[i]) ;
                sum += v[i] ;
            }
            for(int i = 0 ;i<=sum ;i++)
            {
                dp[i] = 1e9 ;    //此处需要特别注意
            }
            dp[0] = 0 ;
            for(int i = 0 ;i<n ;i++)
            {
                for(int j = sum ;j>=v[i] ;j--)
                {
                    dp[j] = min(dp[j],dp[j-v[i]]+w[i]) ;
                }
            }
            int res ;
            for(int i = sum ;i>=0 ;i--)
            {
                if(dp[i] <= W)
                {
                    printf("%d
    ",i) ;
                    break ;
                }
            }
        }
        return 0 ;
    }
    </span>



  • 相关阅读:
    Xshell4连接,Linux系统中文显示乱码解决办法
    Linux系统英文切换中文
    解决VM安装VMTools后错误提示,实现文件共享
    v
    如何安装VM Tool软件包
    Jbpm工作流表补数记录
    【转】Informix数据表结构分析资料整理之约束查询代码
    storm源码之storm代码结构【译】
    Python学习笔记第一天
    python 连接 redis cluster 集群二种方法
  • 原文地址:https://www.cnblogs.com/emoji/p/4436793.html
Copyright © 2020-2023  润新知