HDU1114&BUCU5971——存钱罐——题解
Posted Tisfy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU1114&BUCU5971——存钱罐——题解相关的知识,希望对你有一定的参考价值。
传送门
存钱罐
时间限制:1秒
空间限制:256M
题目描述
存钱罐有个大问题,不打碎存钱罐就无法确定里面有多少钱。
所以可能互出现把存钱罐打碎后发现钱不够的情况。唯一的可能是,称一下存钱罐的重量,试着猜里面有多少钱。
已知存钱罐的重量和每种面值的硬币的重量,请确定存钱罐内的最小金额。
输入描述
第一行包含一个正整数 T T T,表示测试用例的数量。
对于每个测试用例:
第一行都包含两个正整数 e e e和 f ( 1 ≤ e ≤ f ≤ 10000 ) f(1\\leq e\\leq f\\leq 10000) f(1≤e≤f≤10000),分别表示存钱罐和装满硬币的存钱罐的重量(单位:克)。
第二行包含一个整数 n ( 1 ≤ n ≤ 500 ) n(1\\leq n\\leq 500) n(1≤n≤500),表示硬币的总数量。
接下来 n n n行,每行都包含两个整数 p p p和 w ( 1 ≤ p ≤ 50000 , 1 ≤ w ≤ 10000 ) w(1\\leq p\\leq 50000, 1\\leq w\\leq10000) w(1≤p≤50000,1≤w≤10000),分别表示硬币的面值和重量。
输出描述
对于每个测试用例,都输出一行,包含The Minimum amount is x.
,其中x是存钱罐内的最小金额。
若无法确定,则输出Impossible...
样例一
输入
3
10 110
2
1 1
30 50
10 110
2
1 1
30 30
1 6
2
10 3
20 4
输出
The Minimum amount is 60.
The Minimum amount is 100.
Impossible...
题目分析
这是一道完全背包
解题思路
完全背包,对每种硬币的数量没有限制。求解在重量不超过 f − e f-e f−e的情况下存钱罐内的最小金额。
状态表示:
d
p
[
j
]
dp[j]
dp[j]表示重量位
j
j
j的存钱罐内的最小金额。
状态转移方程:
d
p
[
j
]
=
m
i
n
d
p
[
j
]
,
d
p
[
j
−
w
[
i
]
]
+
v
a
l
[
i
]
dp[j]=mindp[j], dp[j-w[i]]+val[i]
dp[j]=mindp[j],dp[j−w[i]]+val[i]
AC代码
#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
int dp[50010]; // dp[j]:重量为j的存钱罐内的最小金额
int val[50010]; // 硬币面值
int w[50010]; // 硬币重量
int main()
int N;
cin >> N;
while (N--)
int e, f;
scanf("%d%d", &e, &f);
int W = f - e;
int n;
cd(n);
for (int i = 0; i < n; i++)
cd(val[i]), cd(w[i]); // scanf
memset(dp, 0x3f, sizeof(dp)); // memset
dp[0] = 0;
for (int i = 0; i < n; i++)
for (int j = w[i]; j <= W; j++)
dp[j] = min(dp[j], dp[j - w[i]] + val[i]);
if (dp[W] < 1e7)
printf("The Minimum amount is %d.\\n",dp[W]);
else
puts("Impossible...");
return 0;
原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/122630623
以上是关于HDU1114&BUCU5971——存钱罐——题解的主要内容,如果未能解决你的问题,请参考以下文章