UVA11264 钱币兑换(dp+贪心+详解)

11 篇文章 0 订阅
6 篇文章 0 订阅

Our dear Sultan is visiting a country where there are n different types of coin. He wants to collect
as many different types of coin as you can. Now if he wants to withdraw X amount of money from a
Bank, the Bank will give him this money using following algorithm.
withdraw(X){
if( X == 0) return;
Let Y be the highest valued coin that does not exceed X.
Give the customer Y valued coin.
withdraw(X-Y);
}
Now Sultan can withdraw any amount of money from the Bank. He should maximize the number
of different coins that he can collect in a single withdrawal.
Input
First line of the input contains T the number of test cases. Each of the test cases starts with n
(1 ≤ n ≤ 1000), the number of different types of coin. Next line contains n integers C1, C2, . . . , Cn
the value of each coin type. C1 < C2 < C3 < . . . < Cn < 1000000000. C1 equals to 1.
Output
For each test case output one line denoting the maximum number of coins that Sultan can collect in a
single withdrawal. He can withdraw infinite amount of money from the Bank.

Sample Input
2
6
1 2 4 8 16 32
6
1 3 6 8 15 20
Sample Output
6
4

题意:予许你取任意钱,求银行给你的最多硬币种类,原则是从最大给起,如有20元和30元硬币,取90元,会给三个30的,取八十的会给2个30和一个20。
思路:
1。第一个必选而不影响最大硬币总数(证明:假设所选硬币中最小的不是第一个硬币,那可以少取一点钱把所选的最小硬币转化成第一个硬币,总硬币数不变)
2。最大值的硬币必取(反证:若不取最大值硬币,所取的钱必然小于最大值硬币,所以可以再取一个最大值硬币而不影响前面所取硬币)
3。设p[i]为c0,c1…ci中所取到的硬币总面值,那么p[i]必然小于c(i+1).(因为如果大的话,就直接取c(i+1)了,而因为已经硬币面值已经从小到大排好,那么小于c(i+1)必然小于c(i+2)…的)
4。那么对于p[i-1]已经取好了,那么对于ci就有两种,取或不取,如果取ci,必然有p[i-1]+ci<c(i+1)(反证:如果取ci且p[i-1]+ci>c(i+1)那么在p[i]中已选的硬币会有一部分转化成c(i+1)面值(大于1种),那硬币种类就减少了。)

ac代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <math.h>
#include <cstdlib>
#include <queue>
#include<iomanip>
using namespace std;
int p[1010],sum,ant;
int main()
{
	int n;
	cin >> n;
	while (n--)
	{
		int m; cin >> m;
		for (int i = 0; i < m; i++)
		{
			cin >> p[i];
		}
		sum = p[0]; ant = 2;//第一个或最后一个必选,先算上。
		if (m <= 2)cout << m << endl;//因为已经排好,那有两个的时候肯定都可以选,一个的时候就 选一个了
		else
		{
			for (int i = 1; i < m-1; i++)
		{
				if ((sum + p[i]) < p[i + 1])
				{
					sum += p[i]; ant++;
				}
		}cout << ant << endl;
	}
	
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值