2019 Multi-University Training Contest 9 Rikka with Coin(贪心)

24 篇文章 0 订阅
19 篇文章 0 订阅

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;
}

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值