题意:题目的意思是有一个储蓄罐,里面放了硬币,只知道储蓄罐装了硬币和没装硬币时的重量,并且知道每种面值硬币的重量。现在要求储蓄罐中可能的最小金额。若储蓄罐中硬币的重量和每种面值硬币的重量不能匹配,则输出impossible。
分析:典型的完全背包,注意初始化。。
//216K 79MS
#include <cstdio>
#include <cstring>
#include <iostream>
#define MIN(A,B) ((A)<(B)?(A):(B))
#define Size_MAX 10001
#define N 505
#define MAX 10000000
int dp[Size_MAX] ;
int weight[N] ;
int val[N] ;
using namespace std ;
void
CompletePack ( int const profit , int const cost , int const v ) //完全背包
//profit代表每种钱币的价值(value),cost代表每种钱币的花费(weight)v ,是钱罐可容纳的最大重量
{
for ( int i = cost ; i <= v ; i ++ )
{
dp[i] = MIN ( dp[i] , dp[i-cost] + profit ) ;
}
}
void
Init_DP ( )
{
for ( int i = 0 ; i < Size_MAX ; i ++ )
{
dp[i] = MAX ;
}
dp[0] = 0 ; //注意完全背包初始化的这个细节
}
void
Solve ( int const kinds , int const v ) // kinds是钱的种类,v 是钱罐可容纳的最大重量
{
for ( int i = 1 ; i <= kinds ; i ++ )
{
CompletePack ( val[i] , weight[i] , v ) ;
}
if ( MAX != dp[v] )
{
printf("The minimum amount of money in the piggy-bank is %d.\n",dp[v]) ;
}
else
{
printf("This is impossible.\n") ;
}
return ;
}
int
main ( )
{
int n ;
scanf ("%d" , & n ) ;
while ( n -- )
{
int e , f ; // e 代表钱罐empty时的重量,f 代表钱罐装满时的最大重量
scanf ("%d%d" , & e , & f ) ;
int v ; // volume
v = f - e ;
Init_DP ( ) ;
int kinds ;
scanf ("%d" , & kinds ) ;
for ( int i = 1 ; i <= kinds ; i ++ )
{
scanf ("%d%d" , & val[i] , & weight[i] ) ;
}
Solve ( kinds , v ) ;
}
return 0 ;
}