贪心算法——找纸币问题
<table border="1" style="font-family:Simsun; border-collapse:collapse; width:80%; padding:0pt 5.4pt"><tbody><tr><td width="882" valign="top" style="width:661.75pt; padding:0pt 5.4pt; border:0.5pt solid rgb(0,0,0)"><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:14pt; font-family:宋体"><strong>问题主题:</strong></span><span style="font-size:10.5pt; font-family:宋体">找钱</span><span style="font-size:14pt; font-family:宋体"/></p></td></tr><tr><td width="882" valign="top" style="width:661.75pt; padding:0pt 5.4pt; border-left-width:0.5pt; border-style:none solid solid; border-left-color:rgb(0,0,0); border-right-width:0.5pt; border-right-color:rgb(0,0,0); border-bottom-width:0.5pt; border-bottom-color:rgb(0,0,0)"><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:14pt; font-family:宋体"><strong>问题描述:</strong></span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'; text-indent:28pt"><span style="font-size:14pt; font-family:宋体">假设有</span><span style="font-size:14pt; font-family:宋体">1<span style="font-family:宋体">元、</span><span style="font-family:Times New Roman">2</span><span style="font-family:宋体">元、</span><span style="font-family:Times New Roman">5</span><span style="font-family:宋体">元、</span><span style="font-family:Times New Roman">10</span><span style="font-family:宋体">元、</span><span style="font-family:Times New Roman">20</span><span style="font-family:宋体">元、</span><span style="font-family:Times New Roman">50</span><span style="font-family:宋体">元、</span><span style="font-family:Times New Roman">100</span><span style="font-family:宋体">的纸币分别为</span><span style="font-family:Times New Roman">c0, c1, c2, c3, c4, c5, c6,</span><span style="font-family:宋体">张。现在要用这些钱来支付</span><span style="font-family:Times New Roman">K</span><span style="font-family:宋体">元,至少要用多少张纸币?如果能找,则输出纸币的张数,不能找则输出</span><span style="font-family:Times New Roman">No</span></span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:14pt; font-family:宋体"><strong>限制条件:</strong></span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'; text-indent:28pt"><span style="font-size:14pt; font-family:宋体">0</span><span style="font-size:14pt; font-family:宋体"><=</span><span style="font-size:14pt; font-family:宋体">c0, c1,c2,c3,c4,c5,c6</span><span style="font-size:14pt; font-family:宋体"><=</span><span style="font-size:14pt; font-family:宋体">1</span><span style="font-size:14pt; font-family:宋体">0</span><span style="font-size:14pt; font-family:宋体; vertical-align:super">9</span><span style="font-size:14pt; font-family:宋体; vertical-align:super"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'; text-indent:28pt"><span style="font-size:14pt; font-family:宋体">0</span><span style="font-size:14pt; font-family:宋体"><=</span><span style="font-size:14pt; font-family:宋体">K</span><span style="font-size:14pt; font-family:宋体"><=10</span><span style="font-size:14pt; font-family:宋体; vertical-align:super">9</span><span style="font-size:14pt; font-family:宋体"/></p></td></tr><tr><td width="882" valign="top" style="width:661.75pt; padding:0pt 5.4pt; border-left-width:0.5pt; border-style:none solid solid; border-left-color:rgb(0,0,0); border-right-width:0.5pt; border-right-color:rgb(0,0,0); border-bottom-width:0.5pt; border-bottom-color:rgb(0,0,0)"><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:14pt; font-family:宋体"><strong>样例:</strong></span><span style="font-size:14pt; font-family:宋体"><strong/></span></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:14pt; font-family:宋体">输入</span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'; text-indent:27pt"><span style="font-size:14pt; font-family:宋体">C0=3, c1=0, c2=2, c3=1, c4=0, c5=3, c6</span><span style="font-size:14pt; font-family:宋体">=</span><span style="font-size:14pt; font-family:宋体">5</span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:14pt; font-family:宋体">输出</span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'; text-indent:27pt"><span style="font-size:14pt; font-family:宋体">6</span><span style="font-size:14pt; font-family:宋体"/></p></td></tr></tbody></table>
### 【解法一】
### 解题分析:
本题使用贪心算法,只需要考虑“尽可能多地使用面值大的纸币”,然后根据面值的大小从大到小排序依次选择。
### 程序实现:
**C++**
<table border="1" style="font-family:Simsun; border-collapse:collapse; width:80%; padding:0pt 5.4pt"><tbody><tr><td width="882" valign="top" style="width:661.8pt; padding:0pt 5.4pt; border:0.5pt solid rgb(0,0,0)"><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">#include</span><span style="font-size:9.5pt; font-family:新宋体"> </span><span style="color:rgb(163,21,21); font-size:9.5pt; font-family:新宋体">"iostream"</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"> </span></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">using</span><span style="font-size:9.5pt; font-family:新宋体"> </span><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">namespace</span><span style="font-size:9.5pt; font-family:新宋体"> std;</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"> </span></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">const</span><span style="font-size:9.5pt; font-family:新宋体"> </span><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> N = 7;</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">static</span><span style="font-size:9.5pt; font-family:新宋体"> </span><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> K = 6200;</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> min(</span><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> num1, </span><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> num2);</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"> </span></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> momeyCount[N] = {3, 0, 2, 1, 0, 3, 5};</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> value[N] = {1, 2, 5, 10, 20, 50, 100};</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"> </span></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"> </span></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> giveChange() {</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> num = 0;</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">for</span><span style="font-size:9.5pt; font-family:新宋体">(</span><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> i = N-1; i >= 0; i --) {</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="font-size:9.5pt; font-family:新宋体"/><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> c = min(K/value[i], momeyCount[i]);</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="font-size:9.5pt; font-family:新宋体"/><span style="font-size:9.5pt; font-family:新宋体">K = K - c * value[i];</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="font-size:9.5pt; font-family:新宋体"/><span style="font-size:9.5pt; font-family:新宋体">num += c;</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="font-size:9.5pt; font-family:新宋体">}</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">if</span><span style="font-size:9.5pt; font-family:新宋体">(K > 0) </span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="font-size:9.5pt; font-family:新宋体"/><span style="font-size:9.5pt; font-family:新宋体">num = -1;</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">return</span><span style="font-size:9.5pt; font-family:新宋体"> num;</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体">}</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"> </span></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> min(</span><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> num1, </span><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> num2) {</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">return</span><span style="font-size:9.5pt; font-family:新宋体"> num1 < num2 ? num1 : num2;</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体">}</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"> </span></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> main() {</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">int</span><span style="font-size:9.5pt; font-family:新宋体"> result = giveChange();</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">if</span><span style="font-size:9.5pt; font-family:新宋体">(result != -1)</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="font-size:9.5pt; font-family:新宋体"/><span style="font-size:9.5pt; font-family:新宋体">cout << result << endl;</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">else</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="font-size:9.5pt; font-family:新宋体"/><span style="font-size:9.5pt; font-family:新宋体">cout << </span><span style="color:rgb(163,21,21); font-size:9.5pt; font-family:新宋体">"NO"</span><span style="font-size:9.5pt; font-family:新宋体"> << endl;</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体"/><span style="color:rgb(0,0,255); font-size:9.5pt; font-family:新宋体">return</span><span style="font-size:9.5pt; font-family:新宋体"> 0;</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:9.5pt; font-family:新宋体">}</span><span style="font-size:9.5pt; font-family:新宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:10.5pt; font-family:宋体"> </span></p></td></tr></tbody></table>
**Java**
~~~
package greed;
import java.util.Arrays;
/**
* 找钱问题
* User: luoweifu
* Date: 14-1-14
* Time: 下午8:08
*/
public class GiveChange {
public static int gaiveChange(MoneyBox[] moneyBoxes, int target) {
Arrays.sort(moneyBoxes);
int count = 0;
for(int i = moneyBoxes.length-1; i >= 0; i--) {
int currentCount = Math.min(moneyBoxes[i].getCount(), target/moneyBoxes[i].getValue());
target -= currentCount*moneyBoxes[i].getValue();
count += currentCount;
}
if(target > 0) {
count = -1;
}
return count;
}
public static void main(String args[]) {
MoneyBox[] moneyBoxes = {
new MoneyBox(1, 3),
new MoneyBox(2, 0),
new MoneyBox(5, 2),
new MoneyBox(10, 1),
new MoneyBox(20, 0),
new MoneyBox(50, 3),
new MoneyBox(100, 5),
};
int result = gaiveChange(moneyBoxes, 620);
if(result > 0)
System.out.println(result);
else
System.out.println("No");
}
}
/**
* 钱盒子
*/
class MoneyBox implements Comparable{
private int value;
private int count;
MoneyBox(int value, int count) {
this.value = value;
this.count = count;
}
int getValue() {
return value;
}
void setValue(int value) {
this.value = value;
}
int getCount() {
return count;
}
void setCount(int count) {
this.count = count;
}
@Override
public int compareTo(Object o) {
MoneyBox moneyBox = (MoneyBox)o;
if(this.value < moneyBox.getValue())
return -1;
else if(this.value == moneyBox.getValue())
return 0;
else
return 1;
}
}
~~~
****
### 算法复杂度:
时间复杂度:如果纸币已经排序(如C++代码),O(n);如果纸币未经排序 (如Java代码),O(nlogn);