zoukankan      html  css  js  c++  java
  • HDU 2191多重背包问题、

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<iostream>
     4 #include<cstring> 
     5 const int qq=2000+50;
     6 int v[qq],w[qq],dp[qq];
     7 using namespace std;
     8 int main()
     9 {
    10     int t;
    11     scanf("%d",&t);
    12     while(t--){
    13         int n,m;
    14         scanf("%d %d",&n,&m);
    15         memset(dp,0,sizeof(dp));
    16         memset(v,0,sizeof(v));
    17         memset(w,0,sizeof(w));
    18         int count=1;
    19         for(int i=0;i<m;++i){
    20             int value,weight,tot;
    21             scanf("%d %d %d",&value,&weight,&tot);
    22             int t=1;
    23             while(tot>=t){
    24                 v[count]=t*value;
    25                 w[count++]=t*weight;
    26                 tot-=t;
    27                 t<<=1;
    28             }
    29             if(tot){
    30                 v[count]=tot*value;
    31                 w[count++]=tot*weight;
    32             }
    33         }
    34         for(int i=1;i<count;++i)
    35             for(int j=n;j>=v[i];--j)        //j必须从n开始dp,如果循序开始dp的话v[i]会被取多次 
    36                 dp[j]=max(dp[j],dp[j-v[i]]+w[i]);     //也就是说达不到01背包要求的v[i]只有取和不取两种状态、 
    37             printf("%d
    ",dp[n]); 
    38     }
    39 }

     算法时间复杂度O(V*∑log n[i])

    总算是理解了为什么要逆序dp

    #include <stdio.h>  
    02.#include <string.h>  
    03.#include <algorithm>  
    04.using namespace std;  
    05.int main()  
    06.{  
    07.    int ncase,p[105],w[105],c[105],dp[105];  
    08.    scanf("%d",&ncase);  
    09.    while(ncase--)  
    10.    {  
    11.        int n,m,count=0;  
    12.        scanf("%d %d",&n,&m);  
    13.        for(int i=0;i<m;i++)  
    14.        scanf("%d %d %d",&p[i],&w[i],&c[i]);  
    15.        memset(dp,0,sizeof(dp));  
    16.        int temp=0;  
    17.        for(int i=0;i<m;i++)  
    18.        {  
    19.            for(int j=n;j>=p[i];j--)//唉在这里又错了几次 要倒着来。  
    20.            {  
    21.                for(int k=1;k<=c[i];k++)  
    22.                {  
    23.                    if(j<k*p[i]) break;  
    24.                    dp[j]=max(dp[j-k*p[i]]+k*w[i],dp[j]);  
    25.                    if(dp[j]>temp)  
    26.                    temp=dp[j];  
    27.                }  
    28.            }  
    29.        }  
    30.        printf("%d
    ",temp);  
    31.    }  
    32.    return 0;  
    33.}  

    上述代码是借鉴别人的、   也是多重背包最原始的解法

    时间复杂度O(V*∑n[i])

  • 相关阅读:
    python设计模式之命令模式
    [Shell] 生成日期列表
    [Python] Python 获取文件路径
    [Search] 倒排索引与bool检索
    [NLP] Reformer: The Efficient Transformer
    [Alg] 随机抽样完备算法-蓄水池算法 Reservoir Sampling
    [Chaos] 混沌数学学习资料
    [Alg] 文本匹配-多模匹配-WM算法
    [Alg]文本匹配-单模匹配-Sunday算法
    [Alg] 文本匹配-多模匹配-AC自动机
  • 原文地址:https://www.cnblogs.com/sasuke-/p/5240139.html
Copyright © 2011-2022 走看看