B - Piggy-Bank
在acm能够做任何事情之前, 必须编制预算并获得必要的财政支持。这一行动的主要收入来自IBM。这个想法其实很简单,每当一些会员有一点小钱时,他就会把所有的硬币都扔到小猪存钱罐里。这个过程是不可逆转的, 除非打破猪,否则硬币不能拿出来。过了足够长的时间, 存钱罐里应该有足够的现金来支付所有需要支付的费用。
但存钱罐存在很大问题:不可能确定里面有多少钱。所以我们可能敲破猪才发现没有足够的钱。显然, 我们要避免这种不愉快的情况,唯一的可能是称重猪,并试图猜测里面有多少枚硬币。假设我们能够准确地确定猪的重量, 而且我们知道给定货币的所有硬币的重量。然后在存钱罐里有一些最低数量的钱, 我们可以保证。你的任务是找出这个最坏的情况, 并确定在存钱罐内的最低现金金额。
Input
输入由 T组测试用例组成。它们的数量T是在输入文件的第一行给出的。每个测试用例以包含两个整E和 F 的行开头(E和F以克为单位),它们表明了空猪和装满硬币的猪的重量。两个权重都以克为值。任何猪的重量都不会超过10公斤, 这意味着 1 < = E < = F < = 10000。在每个测试用例的第二行, 有一个整数数字 N (1 < = N < = 500), 给出给定货币中使用的各种硬币的数量。下面是 N 行, 每行都指定一种硬币类型。这些行包含两个整数, P, W (1 < = P < = 50000, 1 < = W < = 10000)。P 是硬币的价值, W是它的重量(以克为单位)。
Output
为每个测试用例只打印一行输出。该行必须包含句子 "The minimum amount of money in the piggy-bank is X." 其中 X 是可以实现的最低金额的硬币。如果无法准确达到总重量, 请打印一行 "This is impossible."
Sample Input
3 10 110 2 1 1 30 50 10 110 2 1 1 50 30 1 6 2 10 3 20 4
Sample Output
The minimum amount of money in the piggy-bank is 60. The minimum amount of money in the piggy-bank is 100. This is impossible.
解析待更新:首先把dp数组全都初始化为正无穷(dp[0]初始化为0),在用背包思想求dp[f]的最小值,
如果dp[f]还是无穷的话则不可能实现,否则就直接输出dp[f]为最小值
AC代码:
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; inline int read() {int x=0,f=1;char c=getchar();while(c!='-'&&(c<'0'||c>'9'))c=getchar();if(c=='-')f=-1,c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return f*x;} typedef long long ll; const int maxn=100000; const int M=1e7+10; const int INF=0x3f3f3f3f; int dp[maxn]; int a[maxn]; int v[maxn]; int w[maxn]; int main() { int t,n; int V,W; scanf("%d",&t); while(t--){ memset(dp,INF,sizeof(dp));//初始化为正无穷 scanf("%d%d",&V,&W); int f=W-V; scanf("%d",&n); dp[0]=0; for(int i=0;i<n;i++){ scanf("%d%d",&v[i],&w[i]); } for(int i=0;i<n;i++){ for(int j=w[i];j<=f;j++){ dp[j]=min(dp[j],dp[j-w[i]]+v[i]); } } if(dp[f]==INF){ printf("This is impossible. "); } else{ printf("%s %d. ","The minimum amount of money in the piggy-bank is",dp[f]); } } return 0; }