• 动态规划--01背包


    01背包问题

    题目https://www.acwing.com/problem/content/2/

    给定n个物品和一个背包,容量为m,每个物品有体积v和价值w两种属性

    选择物品装入背包,使得在不超过背包容量的情况下,价值最大。

     1 #include<iostream>
     2 using namespace std;
     3 const int N=1010;
     4 int v[N],w[N];
     5 int n,m;
     6 int f[N][N];
     7 int main(void){
     8     cin>>n>>m;
     9     for(int i=1;i<=n;i++){
    10     cin>>v[i]>>w[i];
    11     }
    12     //初始化f[0][x]都是0,所以不需要初始化了
    13     for(int i=1;i<=n;i++){
    14         for(int j=0;j<=m;j++){
    15             f[i][j]=f[i-1][j];
    16             if(j>=v[i]){
    17                 f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);
    18             }
    19         }
    20     }
    21     cout<<f[n][m]<<endl;
    22     return 0;
    23 }

    发现第i层只用到了第i-1层的数据,所以我们可以用滚动数组来做。

    1 //+2保证不会有负数
    2 for(int i=1;i<=n;i++){
    3     for(int j=0;j<=m;j++){
    4         f[i%2][j]=f[(i-1+2)%2][j];
    5         if(j>=v[i])
    6             f[i%2][j]=max(f[i%2][j],f[(i-1+2)%2][j-v[i]]+w[i]);
    7         }
    8 }

    另一方面,我们发现 f [ i ] [ j ]只会用到第i-1层比 j 更小的列

    所以我们每次从后往前枚举体积的话,效果和滚动数组是同一个效果,同时将空间优化到了一维

     1 for(int i=1;i<=n;i++){
     2     for(int j=m;j>=0;j--){
     3     if(j>=v[i])
     4         f[j]=max(f[j],f[j-v[i]]+w[i]);
     5     }
     6 }
     7 //同时,可以把if去掉
     8 for(int i=1;i<=n;i++){
     9     for(int j=m;j>=v[i];j--){
    10         f[j]=max(f[j],f[j-v[i]]+w[i]);
    11     }
    12 }
  • 相关阅读:
    JAVA闰年测试与解决非法输入
    Junit介绍与实现
    等价类划分方法的应用
    使用Visual Studio 2013进行UI自动化测试
    简谈软件测试
    【Software Project Management】Quizs
    White box testing
    peer review
    闰年问题
    热烈庆贺清明小长假的到来
  • 原文地址:https://www.cnblogs.com/greenofyu/p/14223767.html
Copyright © 2020-2023  润新知