要求:给出空存钱罐和存钱后存钱罐的重量,给出可能的若干种硬币的面值和重量,求存钱罐装的最小面值,若给定的硬币无法组成存钱罐的增重,则按要求输出。
方法:背包变形题。
1.完全背包变形题。
2.dp[i]表示存钱的重量为i时的最小钱数。
3.状态转移方程:dp[i]=min(dp[i],dp[i-w[j]]+p[j]),j表示硬币种类的下标。
4.注意状态转移时dp[i-w[j]]必须有钱数。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
int main()
{
int t,i,j,k,e,f,n,min1,flag;
int c,p[505],w[505];
int dp[10005];//dp[i]表示重量为i时的最小金额
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&e,&f);
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d%d",&p[i],&w[i]);
}
c=f-e;
memset(dp,inf,sizeof(dp));
for(i=0;i<=c;i++)
{
flag=0;
for(j=0;j<n;j++)
{
if(w[j]<=i&&(dp[i-w[j]]!=0||i==w[j]))
{
dp[i]=min(dp[i],dp[i-w[j]]+p[j]);
flag=1;
}
}
if(flag==0)
dp[i]=0;
}
if(dp[c]==0)
printf("This is impossible.\n");
else
printf("The minimum amount of money in the piggy-bank is %d.\n",dp[c]);
}
}