HDU 6685 [2019 Multi-University Training Contest 9]

Rikka with Coin

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

Solution

现在只有10美分,20美分,50美分,1美元(相当于100美分)的货币,带数量尽可能少的货币去解决他给出的所有价格。一开始有很多的想法,各种排序,取两个价格的最大货币,小货币换大之类的都被队友的一组数据(20,40,50,60,70,110)hack掉了。最后通过枚举了很多数据发现,其实10块钱最多只拿一个就行了,多的可以换成20块;20块最多拿3个,多的会出现用50块替换的最优解,50块最多拿两个,多的换成100块。可以把每一种货币取的数量枚举出来,然后用dfs跑一下现有货币能否组成所需数据,虽然总共套了7层循环,但是其中6层都最大只有3。需要考虑当前价格大于100时,是否需要带100块的情况。

Code

#include
#include
using namespace std;
const int maxn = 1000+5;
typedef long long ll;
const ll inf = 0x3f3f3f3f3f3f3f3f;

int t,n;
ll ans,a[maxn];

bool dfs(ll x, int a, int b, int c) {
	for(int i=0; i<=a; i++) {
		for(int j=0; j<=b; j++) {
			for(int k=0; k<=c; k++) {
				if((ll)(10*i+20*j+50*k) == x) {
					return true;
				}
			}
		}
	}
	return false;
}

int main() {
	cin >> t;
	while(t--) {
		ans = inf;
		cin >> n;
		for(int i=0; i<n; i++) {
			cin >> a[i];
		}
		ll ans1 = 0;
		bool flag = false;
		for(int i=0; i<n; i++) {
			if(a[i]%10) {
				flag = true;
			}
		}
		if(flag) {
			puts("-1");
			continue;
		}
		for(int i=0; i<=1; i++) {  //枚举10块
			for(int j=0; j<=3; j++) {  //枚举20块
				for(int k=0; k<=1; k++) {  //枚举50块
					bool flag = true;
					ll h = 0;
					for(int l=0; l<n; l++) {  //遍历数组
						if(a[l] < 100) {
							if(dfs(a[l],i,j,k)) {  //验证枚举可行性
								continue;
							} else {
								flag = false;
								break;
							}
						} else {
							if(dfs(a[l]%100+100,i,j,k)) {  //假设大于100但是不需要用100块
								h = max(h,(a[l]-100)/100);
							} else if(dfs(a[l]%100,i,j,k)) {  //假设大于100并且需要用100块
								h = max(h,a[l]/100);
							} else {
								flag = false;
								break;
							}
						}
					}
					if(flag) {
						ans = min(ans,i+j+k+h);
					}
				}
			}
		}
		cout << ans << endl;
	}
}

Source

HDU 6685 Rikka with Coin [2019 Multi-University Training Contest 9]

你可能感兴趣的:(HDU,2019HDU多校赛)