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

    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    const int maxm=201,maxn=31;
    int m,n;
    int w[maxn],c[maxn];
    int f[maxn][maxm];
    int max(int x,int y)
    {
        if(x<y)return y;
        else return x;
    }
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        cin>>w[i]>>c[i];
        for(int i=1;i<=n;i++)
        for(int v=m;v>0;v--)
        if(w[i]<=v)f[i][v]=max(f[i-1][v],f[i-1][v-w[i]]+c[i]);
        else f[i][v]=f[i-1][v];
        cout<<f[n][m];
        return 0;
    }

    先把代码写出来,再做解释了。

    背包问题是一种经典的动态规划的试题。

    试题描述:

    经典的 0-1 背包:知道 n 个物品的体积和价值,第 i 个体积为 V[i],价值为 W[i],有一个背包的容积为 C。求在体积不超容积的前提下,背包中可装物品价值的最大值。

    输入:

    第一行:两个整数 n 和 C ;
    第 2 行到第 n+1 行:每行两个整数 Vi 与 Wi,有一个空格分隔。

    输出:

    一个数,表示背包中能得到物品价值的最大值。 

    输入示例:

    2 10
    1 1
    2 2

    输出示例:

    3

    所以根据题目可知这道题还是动态规划(废话);

    重点:

    1. 0-1背包,意味着bool类型的正确或错误,在背包问题中就意味着选择装入或者不装入;

    2.动态规划的方程式:定义状态f[i,v],表示前i件物品放入一个容量为v的背包可以获得的最大值,所以转移方程为 f[i,v]=max(f[i-1,v],f[i-1,v-c[i]]+w[i]);不要忘了用二维数组;

    PS:方案总数为2的N次方(不会打);

    时间复杂度为 O(NV);

    3.经。。。发现f[i,v]是由f[i-1,v-c[i]]和f[i-1,v]两个式子递推而来的(递推没学好的需要补);可是我们又可以采取什么方法取f[i-1,v-c[i]]和f[i-1,v]的值呢?

    这并不容易;但只要你使用 主循环v=v~0的递减循序计算;

    i也就表示为背包中剩余的容量了!;

    (本人很水);

  • 相关阅读:
    剑指Offer 07 重建二叉树
    剑指Offer 06 从尾到头打印链表
    剑指Offer 05 替换空格
    剑指Offer 04 二维数组中的查找
    剑指Offer 03 数组中重复的数字
    leetcode518
    leetcode474
    leetcode376
    leetcode646
    leetcode213
  • 原文地址:https://www.cnblogs.com/FXY-180/p/9365665.html
Copyright © 2011-2022 走看看