题目地址:
https://www.lintcode.com/problem/coin-problem/description
有个人有 n n n块钱,他去买 m m m块钱的东西,对方有无限个面值为 100 , 50 , 20 , 10 , 5 , 2 , 1 100,50,20,10,5,2,1 100,50,20,10,5,2,1的纸币,问对方找钱的时候纸币数量最少的方案对应的纸币数量是多少。
思路是贪心,直接贪心地使用面额尽量大的纸币即可。
算法正确性证明:
设
x
=
100
a
1
+
50
a
2
+
20
a
3
+
10
a
4
+
5
a
5
+
2
a
6
+
a
7
x=100a_1+50a_2+20a_3+10a_4+5a_5+2a_6+a_7
x=100a1+50a2+20a3+10a4+5a5+2a6+a7并且是最优解,那么容易看到
a
7
≤
1
a_7\le 1
a7≤1,
a
6
≤
2
a_6\le 2
a6≤2(
2
+
2
+
2
=
5
+
1
2+2+2=5+1
2+2+2=5+1),
a
5
≤
1
a_5\le 1
a5≤1,
a
4
≤
1
a_4\le 1
a4≤1,
a
3
≤
2
a_3\le 2
a3≤2,
a
2
≤
1
a_2\le 1
a2≤1,并且
a
7
=
1
,
a
6
=
2
a_7=1,a_6=2
a7=1,a6=2不能同时成立,
a
3
=
2
,
a
4
=
1
a_3=2,a_4=1
a3=2,a4=1也不能同时成立,所以有
50
a
2
+
20
a
3
+
10
a
4
+
5
a
5
+
2
a
6
+
a
7
<
100
50a_2+20a_3+10a_4+5a_5+2a_6+a_7<100
50a2+20a3+10a4+5a5+2a6+a7<100,所以
a
1
=
x
/
100
a_1=x/100
a1=x/100,接着还有
20
a
3
+
10
a
4
+
5
a
5
+
2
a
6
+
a
7
<
50
20a_3+10a_4+5a_5+2a_6+a_7<50
20a3+10a4+5a5+2a6+a7<50,所以
a
2
=
(
x
−
x
/
100
∗
100
)
/
50
a_2=(x-x/100*100)/50
a2=(x−x/100∗100)/50,依次类推。所以贪心法正确。
代码如下:
public class Solution {
/**
* @param n: The guest paid
* @param m: the price
* @return: the sum of the number of banknotes
*/
public int coinProblem(int n, int m) {
// Write your code here
int[] coins = {100, 50, 20, 10, 5, 2, 1};
int x = n - m;
int res = 0;
for (int i = 0; i < coins.length; i++) {
res += x / coins[i];
x %= coins[i];
}
return res;
}
}
时空复杂度 O ( 1 ) O(1) O(1)。