zoukankan      html  css  js  c++  java
  • 01背包问题

    有N个物品和一个容量为V的背包,第i件物品的体积为v(i),价值为w(i),求将哪些物品装入背包,使得背包中物品的总价值最大。 例题: 输入: 4 6 1 4 2 6 3 12 2 7 输出: 23 分析如下: 图片1 图片2图片3
    #include
    using namespace std ;
    int main()  {
        int n , V ;                       //n件物品,背包容量为V
        cin >> n >> V ;
        int v[100] , w[100] ;             //第i件物品,体积为v[i],价值为w[i]
        for(int i = 1 ; i <= n ; i++)       
            cin >> v[i] >> w[i] ;
        int c[10][100] = {0} ;            //c[i][j] 选择第i件物品,背包容量为j时,背包的最大价值
        for(int i = 1 ; i <= n ; i++)   {
            for(int j = 1 ; j <= v[i] - 1 ; j++)            //背包容量小于第i个物品体积时,则不能放入背包
                c[i][j] = c[i-1][j] ;
            for(int j = v[i] ; j <= V ; j++)                //背包容量大于第i个物品体积时,分析放入该物品与不放该物品,哪个使得背包价值最大
                c[i][j] = max(c[i-1][j],c[i-1][j-v[i]]+w[i]) ;
        }
        cout << c[n][V] << endl ;           //输出n个物品中,背包容量为V时,背包的最大价值
        return 0 ;
    }
    
    由于取物品时没有先后顺序,取得当前物品时,背包最大价值只与上一状态有关,所以可以对数组C进行相应处理,以减少空间的使用:
    #include
    using namespace std ;
    int main()  {
        int n , V ;
        cin >> n >> V ;
        int v[100] , w[100] ;
        int c[2][100] = {0} ;
        int t = 0 ;
        for(int i = 1 ; i <= n ; i++)
            cin >> v[i] >> w[i] ;
        for(int i = 1 ; i <= n ; i++)   {
            for(int j = 1 ; j < v[i] ; j++)
                c[t][j] = c[!t][j] ;
            for(int j = v[i] ; j <= V ; j++)
                c[t][j] = max(c[!t][j],c[!t][j-v[i]]+w[i]) ;
            t = !t ;
        }
        if(n&1)
            cout << c[0][V] << endl ;
        else
            cout << c[1][V] << endl ;
        return 0 ;
    }
    
    下面这种方法是对上面方法的一种改进,直接倒序比较,相应代码如下: 图片2 图片3
    #include
    using namespace std ;
    int main()  {
        int n , V ;
        cin >> n >> V ;
        int v[100] , w[100] , dp[100] = {0} ;
        for(int i = 0 ; i < n ; i++)        
            cin >> v[i] >> w[i] ;
        for(int i = 0 ; i < n ; i++)        
            for(int j = V ; j >= v[i] ; j--)          // 保证能放下该物品 
                dp[j] = max(dp[j],dp[j-v[i]]+w[i]) ;  // 确定的容量下,放该物品与不放该物品,哪个能使背包价值最大
        cout << dp[V] << endl ;
        return 0 ;
    }
    
  • 相关阅读:
    Hibernate sqlserver 的对象转成 Hibernate mysql 的对象时 需注意
    将绿色版Tomcat服务添加到系统服务并设为开机运行
    进程上下文和中断上下文
    关于上、下拉电阻的总结整理
    I2C设备驱动流程
    MTK6573的LDO控制
    iomem—I/O映射方式的I/O端口和内存映射方式的I/O端口
    Linux I2C子系统分析I2C总线驱动
    Camera读取ID方法总结
    Linux 信号signal处理机制
  • 原文地址:https://www.cnblogs.com/NYNU-ACM/p/4236863.html
Copyright © 2011-2022 走看看