• 背包问题总结


     我对于dp的使用仍然很不熟练,总结一下各种背包梳理一下。

    01背包

    1 void Knapsack_01(){
    2     memset(dp,0,sizeof(dp));
    3     for(int i=0;i<n;i++){
    4         for(int j=W;j>=w[i];j--){
    5             dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
    6         }
    7     }
    8     printf("%d
    ",dp[W]);
    9 }

    完全背包

    1 void Knapsack_prefect(){
    2     memset(dp,0,sizeof(dp));
    3     for(int i=0;i<n;i++){
    4         for(int j=w[i];j<=W;j++){
    5             dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
    6         }
    7     }
    8     printf("%d
    ",dp[W]);
    9 }

    w很大的01背包

     1 void BigW_01(){
     2     memset(dp,0x3f,sizeof(dp));
     3     dp[0]=0;
     4     for(int i=0;i<n;i++){
     5         for(int j=MAX_N*MAX_V;j>=v[i];j--){
     6             dp[j]=min(dp[j],dp[j-v[i]]+w[i]);
     7         }
     8     }
     9     int ans=0;
    10     for(int i=0;i<=MAX_N*MAX_V;i++)if(dp[i]<=W)ans=i;
    11     printf("%d
    ",ans);
    12 }

    w很大的完全背包

     1 void BigW_prefect(){
     2     memset(dp,0x3f,sizeof(dp));
     3     dp[0]=0;
     4     for(int i=0;i<n;i++){
     5         for(int j=v[i];j<=MAX_N*MAX_V;j++){
     6             dp[j]=min(dp[j],dp[j-v[i]]+w[i]);
     7         }
     8     }
     9     int ans=0;
    10     for(int i=0;i<=MAX_N*MAX_V;i++)if(dp[i]<=W)ans=i;
    11     printf("%d
    ",ans);
    12 }

    多重背包

    复杂度O(nWlog(m))。

    算法思想是可以利用1,2,4,…,2k+a来表示一个数,因此,可以把m个相同物品看作是log(m)种不同的物品做01背包求解。

    总之mi=1+2+4+…+a(0<=a<2k+1)

    这样问题就转化为了nlog(m)个物品求01背包。

    本题还有另一种复杂度为O(nW)的做法,利用了双端队列滑动最小值的思想,反正我是没看懂。之后看懂了补上。

     1 void knapsack_multi(){
     2     memset(dp,0,sizeof(dp));
     3     for(int i=0;i<n;i++){
     4         int num=m[i];
     5         for(int k=1;num>0;k<<=1){
     6             int mul=min(k,num);
     7             for(int j=W;j>=w[i]*mul;j--){
     8                 dp[j]=max(dp[j],dp[j-w[i]*mul]+v[i]*mul);
     9             }
    10             num-=mul;
    11         }
    12     }
    13     printf("%d
    ",dp[W]);
    14 }
  • 相关阅读:
    3.27上午
    3.24上午 补
    2017.3.27下午
    2017.3.27上午
    2017.3.24下午
    2017.3.24上午
    2017.3.23下午
    2017.3.23上午
    2017.3.22上午
    2017.3.21下午
  • 原文地址:https://www.cnblogs.com/bestefforts/p/8990866.html
Copyright © 2020-2023  润新知