码迷,mamicode.com
首页 > 其他好文 > 详细

CDOJ 1264 人民币的构造

时间:2015-12-12 20:09:10      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:

---恢复内容开始---

我们都知道人民币的面值是1、2、5、10,为什么是这个数值呢,我们分析了下发现,从1−10的每个数字都可以由每种面值选出至多一张通过加法和减法(找钱)来构成,(比如:1+2=3,5−1=4,5+1=6,5+2=7,1+2+5=8,10−1=9)

但是实际上,我们只需要1、2、7三种面值就可以组成1−10的每一个数字了

(1+2=3,7−1−2=4,7−2=5,7−1=6,7+1=8,7+2=9,7+1+2=10)

那么现在问题来了,给一个数n,请问最少需要多少种不同的面值就可以构成从1−n的所有数字,注意在构成每一个数字时同种面值不能超过1张。

Input

一个数字n(1<=n<=100000)

Output

一个数字,代表最少需要多少种不同的面值可以构成从1−n的所有数字。

Sample input and output

Sample InputSample Output
10
3

 

 

 

分析:

事实上题面是有点迷惑人的,因为前三个最佳的面额并不是1,2,7,而是1, 3, 9

1, 2, 7只能表示1-10的数,但1, 3, 9可以表示1-13的数。

我们用A[n]表示第n个面额,用sum[n]表示前n个面额之和,不难看出A[1], A[2]……A[n]能表示的范围为1,2……sum[n]

题目要求面额最小,也就相当于A[1]……A[n]能表示的范围尽可能的大,所以

 

|-----------A[n]  A[n]+1-----------------------------------------------------------------A[n+1]--------------------------------------------------|

                             |--------------------------sum[n]-------------------------------------|

A[n+1] - sum[n] = A[n] + 1

据此,可以写出代码

 1 #include <cstdio>
 2 
 3 using namespace std;
 4 
 5 int main() {
 6   int n;
 7   int cnt = 1;
 8   int sum = 1;
 9   int nw = 1;
10   scanf("%d", &n);
11   while (sum < n) {
12     nw = sum*2+1;
13     sum += nw;
14     cnt++;
15   }
16   printf("%d\n", cnt);
17 
18   return 0;
19 }

 

事实上这并不是最简洁的方法,

gdb中观察上面代码,不难发现A[n]为1, 3, 9, 27……

猜想A[n]=3n-1

证明嘛……我再想想。

---恢复内容结束---

CDOJ 1264 人民币的构造

标签:

原文地址:http://www.cnblogs.com/cfeitong/p/5041704.html

踩
(0)
赞
(0)
   
举报
评论 一句话评论(0)
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!