HDU--1114 Piggy-Bank(完全背包)

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

翻译:一个存钱罐,不打破存钱罐,计算其里面最少多少钱。
这是一个完全背包问题。因为每一种面额的钱都是可以无限次的使用。
数据T为测试的个数。E和F分别为空存储罐的重量和装满钱后的重量。
N为硬币种类个数,然后分别输入p[i]和w[i] (1<=i<=N) p为价值,
w为重量。

             dp[v]=min{ dp[v] , dp[v-c[i]]+w[i] }

第一这个问题求的是最小值。第二 这个问题要求满足最后存钱罐是“装满”
因此在递推关系式 和 初始化的时候都需要注意。

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

const int INF=0XFFFFFF;

int main()
{
  int T,E,F,N,p[510],w[510],dp[10000],V;
  scanf("%d",&T);
  while (T--)
  {
    //输入数据
    scanf("%d%d",&E,&F);
    V=F-E;
    scanf("%d",&N);
    for (int i=1;i<=N;i++)
      scanf("%d%d",&p[i],&w[i]);
    
    //数据初始化。dp[0]=0 dp[1...]=INF
    for(int j=0;j<=V;j++)
     dp[j]=INF;
    dp[0]=0;
    
    //利用递推关系
    for(int i=1;i<=N;i++)
      for(int j=w[i];j<=V;j++)
       dp[j]=dp[j]>dp[j-w[i]]+p[i]?dp[j-w[i]]+p[i]:dp[j];

    if(dp[V]!=INF)
      printf("The minimum amount of money in the piggy-bank is %d. ",dp[V]);
    else
      printf("This is impossible. ");
  }
  return 0;
}


关于初始化的一点说明《背包九讲》有涉及:
如果题目不要求要把背包装满,只是要求获得效益最大,那么初始化都是dp[0.....V]=0
如果题目要求将背包装满,那么dp[0]=0 dp[1....V]=-INF 

本题属于第二种情况,需要将背包装满,同时又是求取的最小值,故dp[0]=0 dp[1....V]=INF











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