题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1114
懒了,就不想贴题了。
典型的DP:其实就是找出各种组合的最小值,如果这些硬币的所有组合都不能组成F-E,则这种情况就是不可能发生的。
当一种硬币进来,重量为w,面额为p。那么dp[F-E] = min(dp[F-E],dp[F-E-w] + p);递推,一步步更新DP就可以了。
#include<stdio.h>
#include<LIMITS.H>
struct tu
{
int p;
int w;
}s[505];
int dp[10005];
inline int min(const int a, const int b)
{
return a < b ? a : b;
}
void main()
{
int i,j;
int E,F;
int T;
int N;
scanf("%d", &T);
while(T--)
{
scanf("%d %d", &E, &F);
scanf("%d", &N);
for(i = 0; i < N; ++i)
{
scanf("%d %d",&s[i].p, &s[i].w);
}
F -= E;
for(i = 1; i <= F; ++i)
{
dp[i] = INT_MAX;
}
dp[0] = 0;
for(i = 0; i < N; ++i)
{
for(j = 0; j + s[i].w <= F; ++j)
{
//如果j是当前硬币的整数倍,或者该dp[j]已经被标记过
if(dp[j] != INT_MAX || !(j % s[i].w))
{
dp[j + s[i].w] = min(dp[j + s[i].w], dp[j] + s[i].p);
}
}
}
if(dp[F] < INT_MAX)
{
printf("The minimum amount of money in the piggy-bank is %d.\n",dp[F]);
}
else
{
printf("This is impossible.\n");
}
}
}