zoukankan      html  css  js  c++  java
  • HDU--2191 汶川地震购米(多重背包)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2191

    分析:有资金n元,而市场有m种大米,每种大米价格不等,重量不等,数量不等,
    并且只能整袋购买。如何用有限的资金最多能采购多少公斤粮食呢?
    在这里价格相当与传统多重背包的“花费”而重量是“价值”。
        dp[j]=max{ dp[j-k*c[i]+w[i]]  |  0<=k<=n[i] }
    这里将多重背包转换为01背包和完全背包。

    #include<stdio.h>
    #include<string.h>

    int dp[110],n;

    void ZeroOnePack(int cost,int weight)
    {
      for(int j=n;j>=cost;j--)
        dp[j]=dp[j]>dp[j-cost]+weight?dp[j]:dp[j-cost]+weight;
    }

    void ComplelePack(int cost,int weight)
    {
      for(int j=cost;j<=n;j++)
        dp[j]=dp[j]>dp[j-cost]+weight?dp[j]:dp[j-cost]+weight;
    }


    void MultiplePack(int cost,int weight,int amount)
    {
      if(cost*amount>n)
      {
        ComplelePack(cost,weight);
        return;
      }
      int k=1;
      while (k<=amount)
      {
        ZeroOnePack(k*cost,k*weight);
        amount-=k;
        k*=2;
      }
      ZeroOnePack(amount*cost,amount*weight);
    }

    int main()
    {
      int C,m,p[102],h[102],num[102];
      scanf("%d",&C);
      while (C--)
      {
        //读取数据
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
          scanf("%d%d%d",&p[i],&h[i],&num[i]);

        //初始化  不需要“装满”
        memset(dp,0,sizeof(dp));

        //多重背包问题
        for(int i=1;i<=m;i++)
          MultiplePack(p[i],h[i],num[i]);

        printf("%d ",dp[n]);
      }
      return 0;
    }






  • 相关阅读:
    linux ioctl
    pkg-config用法和gcc cflags
    boost noncopyable类
    google protobuf使用2
    跨平台编译CMake使用
    Linux epoll
    docker安装
    python 脚本转成exe可执行程序
    shell相关知识
    tcpdump使用
  • 原文地址:https://www.cnblogs.com/gt123/p/3456983.html
Copyright © 2011-2022 走看看