zoukankan      html  css  js  c++  java
  • 01背包基础 (杭电2602)

    01背包问题:

    有一个体积为V的背包,有n件物品,每件物品的体积,价值分别为w[i],p[i];要从n件物品中选些放入背包中,使背包里物品的总价值最大。

    动态方程:c[i][j]=max(c[i-1][j],c[i-1][j-w[i]]+p[i]).

    有关动态方程方面的代码:


    for (int i = 1; i <= n; i++) {    
      for (int j = 1; j <= total_weight; j++) {    
        if (w[i] > j) {    
          c[i][j] = c[i-1][j];    
        } 
    	else {                      //也能够用<span style="font-family: KaiTi_GB2312;font-size:18px;">c[i][j]=max(c[i-1][j],c[i-1][j-w[i]]+p[i])取代以下的</span>
            if (c[i-1][j] > v[i]+c[i-1][j-w[i]]) {    
              c[i][j] = c[i-1][j];    
            }    
            else {    
              c[i][j] =  v[i] + c[i-1][j-w[i]];    
            }    
        }    
      }    
    }    
    在杭电2602中我们就能够非常舒服的用01背包解决:

    题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=2602

    刚開始学习的人代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    
    int c[1011][1011];
    int max(int a,int b)
    {
        return a>b?a:b;
    }
    
    int knapsack(int m,int n)
    {
        memset(c,0,sizeof(c));
        int i,j,val[1001],V[1001];
        for(i=1;i<=n;i++)
            scanf("%d",&val[i]);
        for(i=1;i<=n;i++)
            scanf("%d",&V[i]);
        for (i = 1; i <= n; i++)
            {
          for (j = 1; j <= m; j++)
            {
            if (V[i] > j)
            {
            c[i][j] = c[i-1][j];
            }
        else
            {
               c[i][j]=max(c[i-1][j],c[i-1][j-V[i]]+val[i]);
            }
        }
      }
      return (c[n][m]);
    }
    
    int main()
    {
        int t,n,m;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            printf("%d
    ",knapsack(m,n));
        }
        return 0;
    }


    这个问题代码须要优化,降低时间空间复杂度,

    (优化后代码)AC代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    int c[1011];
    
    int max(int a,int b)
    {
        return a>b?a:b;
    }
    int knapsack(int m,int n)
    {
        memset(c,0,sizeof(c));
        int i,j,val[1001],V[1001];
        for(i=1;i<n+1;i++)
            scanf("%d",&val[i]);
        for(i=1;i<n+1;i++)
            scanf("%d",&V[i]);
        for(i=1;i<n+1;i++)
            for(j=m;j>=V[i];j--)
                c[j]=max(c[j-V[i]]+val[i],c[j]);
        return(c[m]);
    }
    int main()
    {
        int t,n,m;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            printf("%d
    ",knapsack(m,n));
        }
        return 0;
    }
    



  • 相关阅读:
    7-3 列表或元组的数字元素求和 (20 分)
    7-2 一帮一 (15 分)
    7-11 字典合并 (40 分)
    7-6 统计工龄 (20 分)
    7-5 统计字符出现次数 (20 分)
    7-4 分析活动投票情况 (20 分)
    7-3 四则运算(用字典实现) (30 分)
    7-22 找鞍点 (20 分)
    制作 U 盘启动盘
    mysql 多表连接的
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4197166.html
Copyright © 2011-2022 走看看