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;
    }
    



  • 相关阅读:
    Codeforces 631A Interview【模拟水题】
    Codeforces 651E Table Compression【并查集】
    Codeforces 651D Image Preview【二分+枚举】
    Codeforces 651C Watchmen【模拟】
    Codeforces 651B Beautiful Paintings【贪心】
    18.06.26 16年期末10:游览规划
    18.06.25 POJ4129 16年期末09:变换的迷宫
    18.06.25 POJ4150 16年期末07:上机
    18.06.25 16年期末06 42点
    18.06.25 16年期末01-05集合
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4197166.html
Copyright © 2011-2022 走看看