Piggy Bank(DP)
题目大意
给储钱罐的质量以及存钱后钱和储钱罐的总质量,以及各种面值硬币的质量,求储钱罐中存款金额的最小值。
题目分析
基础DP,以dp[ m ] 记录储钱罐中硬币总质量不超过m可能的最小金额,遍历1~m,每遍历到一个质量,要再遍历各种面值硬币(记为第 i 种硬币,质量为M[i],面值为V[i]),若dp[ m - M[ i ] ] 存在,证明硬币总质量m可以得到,在dp[ m ] 和dp[ m - M[ i ] ]+V[ i ]中取最小值,即递推关系为 dp[ i ] = min(dp[ i ] ,dp[ m - M[ i ] ]+V[ i ]。注意有可能存在面值相同质量不同的情况。
代码
#include<stdio.h>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<stack>
#define INF 1000000000
using namespace std;
int v[505],w[505];
int dp[10005];
int E,F,N;
void solve()
{
for(int m=1;m<=(F-E);m++)//遍历所有质量
{
for(int i=1;i<=N;i++)//遍历所有硬币
{
if(m-w[i]>=0&&dp[ m-w[i] ]!=INF)
{
dp[m]= min( dp[m],( dp[m-w[i]]+v[i] ) );
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
for(int i=1;i<10005;i++)
{
dp[i]=INF;//若dp[i]==INF,说明总质量为m的硬币不可得到
}
scanf("%d%d",&E,&F);
scanf("%d",&N);
for(int i=1;i<=N;i++)
{
scanf("%d%d",&v[i],&w[i]);
}
solve();
if(dp[F-E]==INF){
printf("This is impossible.\n");
}else{
printf("The minimum amount of money in the piggy-bank is %d.\n",dp[F-E]);
}
}
return 0;
}