题目意思
在ACM做任何事情之前,必须准备预算并获得必要的财务支持。此操作的主要收入来自不可逆绑定资金。背后的想法很简单。每当ACM成员有少量钱时,他都会拿走所有硬币并将它们扔进存钱罐。您知道此过程是不可逆的,如果不破坏存钱罐就无法取出硬币。经过足够长的时间后,存钱罐中应该有足够的现金来支付所有需要支付的款项。
但是存钱罐有一个大问题。无法确定里面有多少钱。因此,我们可能将存钱罐弄成碎片,只是发现没有足够的钱。显然,我们要避免这种不愉快的情况。唯一的可能性是称量存钱罐,然后尝试猜测里面有多少硬币。假设我们能够准确地确定存钱罐的重量,并且知道给定货币的所有硬币的重量。然后,我们可以保证存钱罐中有一些最低限度的钱。您的任务是找出最坏的情况,并确定存钱罐内的最低现金量。我们需要你的帮助。不再有过早损坏的存钱罐!
理解
给出一个存钱罐,能存m克的钱币,有n中硬币,每中硬币有各自的面值以及重量,每种硬币可以无限个数放入存钱罐,最后求出当存钱罐恰好装满时的最少价值,如果不能装满,则输出This is impossible。
- 这题类似完全背包问题,钱币个数不限,求装满时的最小价值。采用如下伪代码。
用dp[i]表示装了i克物品的价值,由于要求最小值则需要将数组初始化inf。
代码
#include<iostream>
#include<cstdio>
using namespace std;
const int inf = 0x3f3f3f3f;
int main(){
int t;
scanf("%d",&t);
while(t--){
int e,f,m;
scanf("%d%d",&e,&f);
m=f-e;
int dp[10010],n,minn=inf,v[10010],w[10010];
fill(dp,dp+10010,inf);
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d",&v[i],&w[i]);
}
dp[0]=0;
for(int i=0;i<n;i++){
for(int j=w[i];j<=m;j++){
dp[j]=min(dp[j],dp[j-w[i]]+v[i]);
}
}
if(dp[m]!=inf) printf("The minimum amount of money in the piggy-bank is %d.\n",dp[m]);
else printf("This is impossible.\n");
}
return 0;
}