hdu-6685 Rikka with Coin 贪心 想法

hdu-6685 Rikka with Coin 贪心 想法

http://acm.hdu.edu.cn/showproblem.php?pid=6685

题意

给一个不超过100的数组,每个元素代表价格,需要最少携带多少个,10/20/50/100面额的硬币,可以购买任意一个物品。

思路

突破口是,10面额到10个,20面额到5个,50面额到2个,(因为一旦超过就可以用100面额替代更优),好像如果枚举小面额,就大概能知道100面额的有多少个了,枚举次数也才100的复杂度,那就三层for枚举吧。

然后怎么算100有多少个,我是这样做的,

本身再三层for枚举一下,是不是当前的硬币可以凑出当前的ai,如果ai比较大,可以i试着去掉一些100去检查。我们枚举的面额最多是220,所以先降到到200+ai%100检查一下,然后再降到100+ai%100检查一下,就可以了。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <bits/stdc++.h>
//#include <stdio.h>
//#include <algorithm>
#define per(i, a, b) for(int i=(a);i<=b;i++)
#define _debug(x) cerr<<#x<<" = "<<x<<endl
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 59;
const ll MOD = 1e9 + 7;
const ll INF = 1e9 + 59;

int kase, n, ans;
int a[105];
int b[105];


bool chek(int x, int i, int j, int k) {
//10 20 50;
per(_10, 0, i)
per(_20, 0, j)
per(_50, 0, k)
if (_10 * 10 + _20 * 20 + _50 * 50 == x)
return true;
return false;
}


int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);

cin >> kase;
while (kase--) {
ans = INF;
cin >> n;

for (int i = 1; i <= n; ++i)
cin >> a[i];


per(_10, 0, 10)
per(_20, 0, 5)
per(_50, 0, 2) {
int _100 = 0;
bool valid = true;
for (int i = 1; valid && i <= n; ++i) {
if (chek(a[i], _10, _20, _50)) {
_100 = max(_100, 0);
} else if (a[i] >= 300 && chek(a[i] % 100 + 200, _10, _20, _50)) {
_100 = max(_100, a[i] / 100 - 2);
} else if (a[i] >= 200 && chek(a[i] % 100 + 100, _10, _20, _50)) {
_100 = max(_100, a[i] / 100 - 1);
} else if (a[i] >= 100 && chek(a[i] % 100, _10, _20, _50)) {
_100 = max(_100, a[i] / 100);
} else {
valid = false;
}
}
if (valid)
ans = min(ans, _10 + _20 + _50 + _100);
}
if (ans == INF)ans = -1;
cout << ans << endl;
}


return 0;
}

/*



*/
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×