HDU--1171 Big Event in HDU(多重背包)

题目http://acm.hdu.edu.cn/showproblem.php?pid=1171
分析:输入N种设备,已知设备的价值和数量。然后根据总价值将这批设备均分
给两个计算机系。输出包括这两个系分别获得设备的价值,要求计算机系的价值不小于软件系。
一个多重背包问题,将总价值的二分之一作为背包的容量,依次将设备选入背包。
背包可以是不装满的。

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

int dp[260000],V;

//01背包
void ZeroOnePack(int c,int w)
{
  for(int i=V;i>=c;i--)
    dp[i]=dp[i]>dp[i-c]+w?dp[i]:dp[i-c]+w;
}

//完全背包
void CompletePack(int c,int w)
{
  for(int i=c;i<=V;i++)
    dp[i]=dp[i]>dp[i-c]+w?dp[i]:dp[i-c]+w;
}

//多重背包
void MultiplePack(int c,int w,int amount)
{
  if(c*amount>=V)
  {
    CompletePack(c,w);
    return;
  }
  int k=1;
  while (k<=amount)
  {
    ZeroOnePack(k*c,k*w);
    amount-=k;
    k*=2;
  }
  ZeroOnePack(amount*c,amount*w);
}


int main()
{
  int N,v[51],n[51],sum;
  while (scanf("%d",&N)!=EOF)
  { 
    //获取数据
    if(N<0) break;
    sum=0;
    for(int i=1;i<=N;i++)
    {
      scanf("%d%d",&v[i],&n[i]);
      sum+=v[i]*n[i];
    }

    //初始化  背包可以不装满
    V=sum/2;
    memset(dp,0,sizeof(dp));

    for(int i=1;i<=N;i++)
      MultiplePack(v[i],v[i],n[i]);

    //背包最后的总价值dp[v]<=sum/2  sum-dp[V]>=sum/2
    printf("%d %d ",sum-dp[V],dp[V]);
  }
  return 0;
}





原文地址:https://www.cnblogs.com/gt123/p/3457366.html