UVa 11264 Coin Collector (選硬幣&貪心好題)
11264 - Coin Collector
Time limit: 3.000 seconds
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
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 |
Sample Output |
2 6 1 2 4 8 16 32 6 1 3 6 8 15 20 |
6 4 |
思路:
1. 你肯定注意到了,面值最大的硬幣c[n-1]必須要選。(反證:如果花了sum元卻沒有選中它,可知sum<c[n-1],於是用m+c[n-1]元去兌換可以得到一個更優解。)
2. 貪心的關鍵:假設S(i)是c[1]…c[i] 中那些被選中的貨幣的面值的和,那麼一定有 S(i) < c[i+1]。(反證:若S(i)>=c[i+1],那銀行肯定要找給他c[i+1]面值的硬幣。)
3. 所以可以構造一個這樣的序列出來。按照2中所說,如果有 S(i-1) < c[i]且S(i) =S(i-1)+c[i]<c[i+1],那麼c[i]將被選中。
完整程式碼:
/*0.015s*/
#include<cstdio>
int c[1005];
int main()
{
int t, n, i, sum, count;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
for (i = 0; i < n; ++i)
scanf("%d", &c[i]);
if (n <= 2) printf("%d\n", n);
else
{
sum = c[0], count = 2;///先把第一個和最後一個算上
for (i = 1; i < n - 1; ++i)
if (sum < c[i] && sum + c[i] < c[i + 1])
sum += c[i], ++count;
printf("%d\n", count);
}
}
return 0;
}