2019杭电多校 第九场 6685-Rikka with Coin【思维+暴力】

2019杭电多校 第九场 6685-Rikka with Coin【思维+暴力】

题目:

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

参考资料:

https://blog.csdn.net/qq_41360176/article/details/99762515

大致题意:

餐厅中有n种不同价格的菜品,你有非常非常多的10美分,20美分,50美分,100美分(1美元)的硬币,问你要最少带多少个硬币能在餐厅中吃任意的菜品且不会被找零。

思路:

一开始我以为是背包,然而大错特错,赛后看题解内心复杂,其实是一道思维+暴力题,分析后会发现
10美分硬币最多拿1个,因为拿2个的话不如拿1*10美分+1*20美分
同理20美分最多拿3个,拿4个的话不如拿1*10美分+2*20美分+1*50美分
50美分最多拿1个,拿2个的话不如拿1*50美分+1*100美分
不过有个两个特例:

有特殊的数据:110 40 60 50 答案是 50+20+20+20 不用拿一百的
还有一种 :10 90 100 答案是 50+20+20+10 也不用拿一百的
如果这个数字是100的倍数,并且当前10 20 50 的硬币可以凑成100,则计算100的硬币少拿一个,110也是类似的判断。

代码:

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f

int judge(int i10, int i20, int i50, int num) {
	for(int i = 0; i <= i10; i++)
		for(int j = 0; j <= i20; j++)
			for(int k = 0; k <= i50; k++)
				if(i*10+j*20+k*50 == num)
					return 1;
	return 0;
}

int main() {
	int t;
	scanf("%d",&t);
	while(t--) {
		int n, flag = 0;
		int a[1000];
		memset(a,0,sizeof(a));
		scanf("%d",&n);
		for(int i = 1; i <= n; i++) {
			scanf("%d",&a[i]);
			if(a[i] % 10 != 0)
				flag = 1;
		}
		if(flag == 1) {
			printf("-1\n");
			continue;
		}
		
		int min_ans = INF;
		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 ans = -1;
					int cnt = 0;
					for(int r = 1; r <= n; r++) {
						int count = a[r] / 100;
						if((a[r]>=100) && (a[r]%100==0) && (judge(i,j,k,100)==1))
							count--;//判断情况100
						else if((a[r]>100) && (a[r]%100==10) && (judge(i,j,k,110)==1))
							count--;//判断情况110
						else if(judge(i,j,k,(a[r] % 100)) == 0)
							break;
						
						ans = max(ans,(count+i+j+k));
						cnt = r;
					}
					if(cnt == n)
						min_ans = min(min_ans, ans);
				}
			}
		}
		printf("%d\n",min_ans);
	}
	return 0;
}

你可能感兴趣的:(补题目)