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

    01背包

    //f[i][j]表示前i件物品花费j元的最大价值
    //f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+c[i])
    //f[i][0]=0 f[0][j]=0

    1、普通解法

     1 //f[i][j]表示前i件物品花费j元的最大价值
     2 //f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+c[i])
     3 //f[i][0]=0 f[0][j]=0
     4 
     5 #include <bits/stdc++.h>
     6 using namespace std;
     7 int f[105][105];
     8 int m,n;
     9 int w[105],c[105]; 
    10 
    11 int main(){
    12     freopen("in1.txt","r",stdin); 
    13     cin>>m>>n;
    14     for(int i=1;i<=n;i++){
    15         cin>>w[i]>>c[i];        
    16     }
    17     //初始化dp
    18     int tmp=max(m,n);
    19     for(int i=0;i<=tmp;i++){
    20         f[i][0]=0;
    21         f[0][i]=0;
    22     } 
    23     
    24     for(int i=1;i<=n;i++){
    25         for(int j=1;j<=m;j++){
    26             f[i][j]=f[i-1][j];
    27             if(j>=w[i]){
    28                 f[i][j]=max(f[i][j],f[i-1][j-w[i]]+c[i]);
    29             }
    30         }
    31     }
    32     cout<<f[n][m]<<endl;
    33     
    34     return 0;
    35 } 
    36 
    37 
    38 //单数组
    39 //可以边读入边动态规划么 
    01背包

    2、边读入边dp

    因为f[i][j]表示前i件物品花费j元的最大价值

    算到f[i][j]的时候只需要用到前i种物品

     1 //f[i][j]表示前i件物品花费j元的最大价值
     2 //f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+c[i])
     3 //f[i][0]=0 f[0][j]=0
     4 
     5 #include <bits/stdc++.h>
     6 using namespace std;
     7 int f[105][105];
     8 int m,n;
     9 int w[105],c[105]; 
    10 
    11 int main(){
    12     freopen("in1.txt","r",stdin); 
    13     //初始化dp
    14     memset(f,0,sizeof(f));
    15     
    16     cin>>m>>n;
    17     for(int i=1;i<=n;i++){
    18         cin>>w[i]>>c[i];
    19         for(int j=1;j<=m;j++){
    20             f[i][j]=f[i-1][j];
    21             if(j>=w[i]){
    22                 f[i][j]=max(f[i][j],f[i-1][j-w[i]]+c[i]);
    23             }
    24         }    
    25     }
    26     cout<<f[n][m]<<endl;
    27     
    28     return 0;
    29 } 
    30 
    31 
    32 //单数组
    33 //可以边读入"边动态规划么 
    01背包(边读入边DP)

    3、单维数组优化

    一维数组的情况下,j必须从后往前,不然会导致同一件物品被选多次,而每件物品只有一样 

     1 //f[j]表示前i件物品花费j元的最大价值
     2 //f[j]=max(f[i-1][j],f[i-1][j-w[i]]+c[i])
     3 //f[j]=0
     4 
     5 #include <bits/stdc++.h>
     6 using namespace std;
     7 int f[105];
     8 int m,n;
     9 int w[105],c[105]; 
    10 
    11 int main(){
    12     freopen("in1.txt","r",stdin); 
    13     //初始化dp
    14     memset(f,0,sizeof(f));
    15     cin>>m>>n;
    16     for(int i=1;i<=n;i++){
    17         cin>>w[i]>>c[i];        
    18     }
    19     
    20     //一维数组的情况下,j必须从后往前,不然会导致同一件物品被选多次,没每件物品只有一样 
    21     for(int i=1;i<=n;i++){
    22         for(int j=m;j>=1;j--){
    23             if(j>=w[i]){
    24                 f[j]=max(f[j],f[j-w[i]]+c[i]);
    25             }
    26         }
    27     }
    28     cout<<f[m]<<endl;
    29     
    30     return 0;
    31 } 
    32 
    33 
    34 //单数组
    35 //可以边读入边动态规划么 
    36 //01背包的分组背包
    37 //01背包的分组背包的一维数组优化 
    01背包(单数组优化)

    4、分组背包

    普通解法相当于把k省略了,因为每件物品就一件

     1 //f[i][j]表示前i件物品花费j元的最大价值
     2 //f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+c[i])
     3 //f[i][0]=0 f[0][j]=0
     4 
     5 #include <bits/stdc++.h>
     6 using namespace std;
     7 int f[105][105];
     8 int m,n;
     9 int w[105],c[105]; 
    10 int num[105];//代表每样物品的个数 
    11 
    12 int main(){
    13     freopen("in1.txt","r",stdin); 
    14     cin>>m>>n;
    15     for(int i=1;i<=n;i++){
    16         cin>>w[i]>>c[i];    
    17         num[i]=1;    
    18     }
    19     //初始化dp
    20     int tmp=max(m,n);
    21     for(int i=0;i<=tmp;i++){
    22         f[i][0]=0;
    23         f[0][i]=0;
    24     } 
    25     
    26     //每个物品看做一组,每组只有一个 
    27     for(int i=1;i<=n;i++){
    28         for(int j=1;j<=m;j++){
    29             f[i][j]=f[i-1][j];
    30             for(int k=1;k<=num[i];k++){
    31                 if(j>=w[i]){
    32                     f[i][j]=max(f[i][j],f[i-1][j-w[i]]+c[i]);
    33                 }
    34             }
    35         }
    36     }
    37     cout<<f[n][m]<<endl;
    38     
    39     return 0;
    40 } 
    41 
    42 
    43 //单数组
    44 //可以边读入边动态规划么 
    01背包(分组背包)

    5、分组背包单数组优化

    j还是得从后往前,因为j的顺序只和f数组的维数相关,而和这里的k没有关系

     1 //f[j]表示前i件物品花费j元的最大价值
     2 //f[j]=max(f[i-1][j],f[i-1][j-w[i]]+c[i])
     3 //f[j]=0
     4 
     5 #include <bits/stdc++.h>
     6 using namespace std;
     7 int f[105];
     8 int m,n;
     9 int w[105],c[105]; 
    10 int num[105]; 
    11 
    12 int main(){
    13     freopen("in2.txt","r",stdin); 
    14     //初始化dp
    15     memset(f,0,sizeof(f));
    16     cin>>m>>n;
    17     for(int i=1;i<=n;i++){
    18         cin>>w[i]>>c[i];        
    19         num[i]=1; 
    20     }
    21     
    22     //一维数组的情况下,j必须从后往前,不然会导致同一件物品被选多次,而每件物品只有一样 
    23     
    24     //我们一般01背包只是把k省略了而已,因为k等于1,
    25     //所以加上了k后,我们还是需要将j由后向前枚举 
    26     
    27     for(int i=1;i<=n;i++){
    28         for(int j=m;j>=1;j--){
    29             for(int k=1;k<=num[i];k++){
    30                 if(j>=w[i]){
    31                     f[j]=max(f[j],f[j-w[i]]+c[i]);
    32                 }
    33             }
    34         }
    35     }
    36     cout<<f[m]<<endl;
    37     
    38     return 0;
    39 } 
    40 
    41 
    42 //单数组
    43 //可以边读入边动态规划么 
    44 //01背包的分组背包
    45 //01背包的分组背包的一维数组优化 
    01背包(分组背包单数组优化)
  • 相关阅读:
    Linux系统 SecureCRT SecureFX 注册破解方法
    局域网代理通过wget下载
    Package gtk+-3.0 was not found in the pkg-config search path
    Js获取当前系统时间
    vuex-- Vue.的中心化状态管理方案(vue 组件之间的通信简化机制)
    HTML空格占位符
    vue表单验证--veevalidate使用教程
    vue 时间选择器组件
    js处理数据库时间格式/Date(1332919782070)/
    vue-cli 自定义过滤器的使用
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/7499284.html
Copyright © 2011-2022 走看看