Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1248 Accepted Submission(s): 377
Problem Description
Rikka hates coins, and she used to never carry any coins with her. These days, Rikka is doing her summer internship abroad. Without mobile payment, Rikka has to face strange prices of commodities, and as a result of always using paper currency, she has to face mountainous coins on here table.
In the local currency system, there are 4 kinds of coins: 10 cents, 20 cents, 50 cents and 1 dollar. Up to now, Rikka has gained at least 10100 coins for each kind.
Now, Rikka is going to have dinner in the canteen, and she decides to pay the bill only with coins. There are n different combos in the canteen and the price of the ith is wi cents. Rikka would like to choose one combo as dinner but she has not decided to choose which one yet. Therefore, she wants to take some coins so that whichever she chooses, she can always pay the bill without receiving any change.
Since Rikka hates coins, she wants to carry as few coins as possible with her. As it is generally known that Rikka is not good at math, she wants you to help her make the decision.
Input
The first line of the input contains a single integer T(1≤T≤500), the number of test cases.
For each test case, the first line contains a single integer n(1≤n≤100), the number of combos sold in the canteen.
The second line contains n positive integers w1,…,wn(1≤wi≤109), which represents the prices.
Output
For each test case, output a single line with a single integer which represents the minimum number of coins. If there is no valid solution, output −1.
Hint
In the first test case, one optimal solution is to bring one coin of 10 cents and two coins of 20 cents.
In the second test case, one optimal solution is to bring 5 coins of one dollar.
Sample Input
3 5 10 20 30 40 50 5 100 200 300 400 500 1 1
Sample Output
3 5 -1
Source
2019 Multi-University Training Contest 9
Recommend
chendu | We have carefully selected several similar problems for you: 6690 6689 6688 6687 6686
Statistic | Submit | Discuss | Note
在最后的答案:
对于:
10分的硬币, 最多1个, 若2个, 不如换成1个10, 1个20。
20分的硬币, 最多3个, 若4个, 不如换成1个10, 1个50, 2个20。
50分的硬币, 最多1个, 若2个, 不如换成1个100, 1个50。
所以:
10分的硬币取值范围为[0, 1]。
20分的硬币取值范围为[0, 4]。
50分的硬币取值范围为[0, 1]。
100分的硬币, 需要考虑是否拆出一个, 例如110 可以拆成100 跟 10
但根据10分, 20分, 50分的取值, 只需要考虑100, 110, 120。
考虑完后就是一坨代码了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#ifdef LOCAL
#define debug(x) cout << "[" __FUNCTION__ ": " #x " = " << (x) << "]\n"
#define TIME cout << "RuningTime: " << clock() << "ms\n", 0
#else
#define TIME 0
#endif
#define continue(x) { x; continue; }
#define break(x) { x; break; }
ll mod = 1e9 + 7;
ll fpow(ll a, ll b) { ll res = 1; for (; b > 0; b >>= 1) { if (b & 1) res = res * a % mod; a = a * a % mod; } return res; }
const int N = 1e5 + 10;
int a[N];
int main()
{
#ifdef LOCAL
freopen("D:/input.txt", "r", stdin);
#endif
int t;
cin >> t;
while (t--)
{
int flag = 0, _100 = 0;
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
if (a[i] % 10 != 0)
flag = 1;
}
if (flag)
continue(cout << -1 << endl);
int MI = 0x3f3f3f3f;
for (int i = 0; i <= 1; i++) // 10
for (int j = 0; j <= 3; j++) // 20
for (int k = 0; k <= 1; k++) // 50
{
int MX = 0;
int flag = 0;
for (int u = 1; u <= n; u++)
{
if (a[u] < 100)
{
if (!a[u])
continue;
if (a[u] == 10)
{
if (i >= 1)
continue;
}
else
if (a[u] == 20)
{
if (j >= 1)
continue;
}
else
if (a[u] == 30)
{
if (j >= 1 && i >= 1)
continue;
}
else
if (a[u] == 40)
{
if (j >= 2)
continue;
}
else
if (a[u] == 50)
{
if ((j >= 2 && i >= 1) || k >= 1)
continue;
}
else
if (a[u] == 60)
{
if (j >= 3 || (k >= 1 && i >= 1))
continue;
}
else
if (a[u] == 70)
{
if ((j >= 1 && k >= 1) || (i >= 1 && j >= 3))
continue;
}
else
if (a[u] == 80)
{
if (i >= 1 && j >= 1 && k >= 1)
continue;
}
else
if (a[u] == 90)
{
if (j >= 2 && k >= 1)
continue;
}
}
else // 大于100
{
if (a[u] % 100 + 100 == 110)
{
if (j >= 3 && k >= 1)
{
MX = max(MX, (a[u] - 100) / 100);
continue;
}
}
else
if (a[u] % 100 + 100 == 120)
{
if (i >= 1 && j >= 3 && k >= 1)
{
MX = max(MX, (a[u] - 100) / 100);
continue;
}
}
else
if (a[u] % 100 + 100 == 100)
{
if (i >= 1 && j >= 2 && k >= 1)
{
MX = max(MX, (a[u] - 100) / 100);
continue;
}
}
MX = max(MX, a[u] / 100);
int tem = a[u];
a[u] %= 100;
if (!a[u])
{
a[u] = tem;
continue;
}
if (a[u] == 10)
{
a[u] = tem;
if (i >= 1)
continue;
}
else
if (a[u] == 20)
{
a[u] = tem;
if (j >= 1)
continue;
}
else
if (a[u] == 30)
{
a[u] = tem;
if (j >= 1 && i >= 1)
continue;
}
else
if (a[u] == 40)
{
a[u] = tem;
if (j >= 2)
continue;
}
else
if (a[u] == 50)
{
a[u] = tem;
if ((j >= 2 && i >= 1) || k >= 1)
continue;
}
else
if (a[u] == 60)
{
a[u] = tem;
if (j >= 3 || (k >= 1 && i >= 1))
continue;
}
else
if (a[u] == 70)
{
a[u] = tem;
if ((j >= 1 && k >= 1) || (i >= 1 && j >= 3))
continue;
}
else
if (a[u] == 80)
{
a[u] = tem;
if (i >= 1 && j >= 1 && k >= 1)
continue;
}
else
if (a[u] == 90)
{
a[u] = tem;
if (j >= 2 && k >= 1)
continue;
}
}
flag = 1;
}
if (!flag)
{
MI = min(MI, i + j + k + MX);
}
}
cout << MI << endl;
}
return TIME;
}