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

CDOJ 1264 人民币的构造

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

标签:

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

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

但是实际上,我们只需要127三种面值就可以组成110的每一个数字了

1+2=3712=472=571=67+1=87+2=97+1+2=10

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

Input

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

Output

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

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
迷上了代码!