• 0-1背包问题——动态规划


     1 //  动态规划法解决0-1背包问题
     2 //example:
     3 //物品种类n=5,背包容量c=10,
     4 //物品的重量向量 w={2,2,6,5,4},物品的价值向量 v={6,3,5,4,6}
     5 // O(min{n*c,2^n})
     6 #include "stdafx.h"
     7 #include <cstdlib>
     8 #include <iostream>
     9 
    10 using namespace std;
    11 template<class Type>
    12 Type Knapsack(int n,Type c,Type v[],Type w[],Type**p,int x[])
    13 {
    14  int* head=new int[n+2];
    15  head[n+1]=0;p[0][0]=0;p[0][1]=0;
    16  int left=0,right=0,next=1;
    17  head[n]=1;
    18  for(int i=n;i>=1;i--){
    19     int k=left;
    20     for(int j=left;j<=right;j++){
    21       if(p[j][0]+w[i]>c) break;
    22       Type y=p[j][0]+w[i],m=p[j][1]+v[i]; 
    23       while(k<=right&&p[k][0]<y){
    24         p[next][0]=p[k][0];
    25         p[next++][1]=p[k++][1];                         
    26                                  }     
    27       if(k<=right&&p[k][0]==y){
    28          if(m<p[k][1])  m=p[k][1];
    29          k++;                     
    30                                }
    31       if(m>p[next-1][1]) {p[next][0]=y;p[next++][1]=m;}
    32       while(k<=right&&p[k][1]<=p[next-1][1]) k++;     
    33            
    34             }
    35      while(k<=right){p[next][0]=p[k][0];p[next++][1]=p[k++][1]; }    
    36     left=right+1;right=next-1;head[i-1]=next;     
    37          }
    38  Traceback(n,w,v,p,head,x);
    39  return p[next-1][1];
    40  
    41 }
    42 
    43 template<class Type>
    44 void Traceback(int n,Type w[],Type v[],Type**p,int* head,int x[]){
    45      std::cout<<"物品清单如下:(‘0’表示没有,‘1’表示有)"<<endl;
    46      Type j=p[head[0]-1][0],m=p[head[0]-1][1];
    47      for(int i=1;i<=n;i++)
    48      {
    49        x[i]=0;
    50        for(int k=head[i+1];k<=head[i]-1;k++){
    51                if(p[k][0]+w[i]==j&&p[k][1]+v[i]==m){
    52                  x[i]=1;j=p[k][0];m=p[k][1];break;                                   
    53                                                     }
    54                }      
    55       
    56        std::cout<<""<<i<<"中物品的状态为:";      
    57        std::cout<<x[i]<<endl;
    58      }
    59      
    60      }
    61 
    62 
    63 
    64 int main(int argc, char *argv[])
    65 {
    66     
    67     int w[]={10002,2,2,6,5,4},v[]={1,6,3,5,4,6}; //w和v的首零元素不计入0-1背包问题求解中
    68     //int w[]={1002,4,5,6,2,2},v[]={8,6,4,5,3,6};
    69     //cout<<w[3]<<v[3]<<endl;
    70     int n=5,c=10;
    71     int x[6]={0};
    72     int**  p=new int*[n+100];//数组必须足够大,next可能远大于n
    73     for(int i=0;i<=n+100;i++) p[i]=new int[2];
    74     cout<<"最优背包的解为:"<<endl;
    75     int y=Knapsack(n,c,v,w,p,x);
    76     
    77     cout<<"最大价值:"<<y<<endl;
    78     
    79     return 0;
    80 }

  • 相关阅读:
    CSU software 新手练习1 解题报告
    HDU 4067 Random Maze
    HDU 1853 Cyclic Tour
    Notepad++搭配MinGW编译运行C,C++程序
    ACM POJ3299-Humidex
    开始正常的做题了=。=
    写在杭电热身赛2之后
    大二了~
    Vim 学习笔记之cvim hot key
    The 10th Zhejiang Provincial Collegiate Programming Contest
  • 原文地址:https://www.cnblogs.com/jieforever/p/4696548.html
Copyright © 2020-2023  润新知