• 一道百度面试题200元的组合方式有多少


    /*************************************************
    设计者:cslave
    版本说明:本代码免费用于商用,拷贝,转移,使用,但是
    有本代码导致的问题,本人概不负责。
    设计时间:2012.7.6
    分发原则:遵守GNU规范。如有错误麻烦请通知本人谢谢。
    **************************************************/


    /*********************************************

    题目描述:

    人民币有 1元 2元 5元 10元 20元 50 元 100元 这几种币值.

    问:给定200元,求出有多少种币值组合方式. 币种可重复,比如,200张1元的算一种方式.


    解法:
    依次设 1元 2元 5元 10元 20元 50 元 100元张数为 x,y,z,m,n,p,q
    则有
    x+2y+5z+10m+20n+50p+100q=200 其中
    0=<x<=200
    0=<y=<100
    0=<z=<40
    0=<m=<20
    0=<n=<10
    0=<p=<4
    0=<q=<2

    可以采用for循环迭代输出的方案,但是太朴素。也可以采用
    递归方案:

    F(n)=F(n-1)+F(n-2)+F(n-5)+F(n-10)+F(n-20)+F(n-50)+F(n-100)

    当然也可以采用自底向上的方案来输出,但是耗时都比较长


    我们可以采用一种新的方案:

    x+2y+5z+10m+20n+50p+100q=200 可以分治为

    q=0; x+2y+5z+10m+20n+50p=200 等价于 2y+5z+10m+20n+50p<=200

    q=1; x+2y+5z+10m+20n+50p=100 等价于 2y+5z+10m+20n+50p<=100

    q=2: x+2y+5z+10m+20n+50p=0 只有一种选法


    当q=0时

    设10m+20n+50p=10k,则 2y+5z<=200-10k (0<=k<=20)

    同时 2n+5p<=k;
    所以
    Sum=0;
    for(k=0;k<=20;k++)
    Sum=Count(2y+5z<=200-10k)* Count(2n+5p<=k);

    当q=1时

    设10m+20n+50p=10k,则 2y+5z<=100-10k (0<=k<=10)

    同时 2n+5p<=k;
    所以
    Sum=0;
    for(k=0;k<=10;k++)
    Sum=Count(2y+5z<=100-10k)* Count(2n+5p<=k);

    当q=2时

    仅有一种方案。

    Count来自于格点三角形公式,格点三角形公式是 S=E/2+I-1,
    其中,E表示边界上格点数目,I表示内部的格点数目,S为格点三角形面积。
    边界上格点数目为两个直角边的点数。
    将格点三角形面积公式重写为
    S+E/2=E/2+E/2+I-1 即为 I+E=S+E/2+1;

    下面让我们想想 ,I+E为格点三角形的内部和边界顶点,他们是
    满足2n+5p<=k条件的n和p的对应正整数解。

    让我们通过公式计算 Count(2n+5p<=k)


    对于k%10==0的情况。

    E=8*M/10=4M/5 (列举2n+5p<=10想想就明白了)

    S=(1/2)*(M/2)*(M/5)=M*M/20

    所以I+E=S+1+E/2=M*M/20+1+2M/5


    对于k%10!=0的情况 ,也就是k%10>0
    2n+5p=10t+h (1 <=h <=9)。(t> =1)
    当h为奇数时,p必为奇数 ,解的数目为不超过[(10t+h)/5]的所含奇数的数目

    当h为偶数时,p必为偶数,解的数目为不超过[(10t+h)/5]的所含偶数的数目

    [(10t+h)/5]值本身可能是2t或者2t+1;
    当h=1,3时候 解的个数为t (考虑下 0 ,1,2,...,2t)

    当h=2,4,5,6,7,8,9时,解的个数为t+1 (考虑下 0 ,1,2,...,2t,2t+1)


    所以当h=1,2,3.。。。,9的时候,对应的解个数为
    h 解个数
    0 M*M/20+1+2M/5
    1 t +M*M/20+1+2M/5
    2 2t+1 +M*M/20+1+2M/5
    3 3t+1 +M*M/20+1+2M/5
    4 4t+2 +M*M/20+1+2M/5
    5 5t+3 +M*M/20+1+2M/5
    6 6t+4 +M*M/20+1+2M/5
    7 7t+5 +M*M/20+1+2M/5
    8 8t+6 +M*M/20+1+2M/5
    9 9t+7 +M*M/20+1+2M/5
    好了 到这里不解释了,写代码吧。

    *********************************************/

    View Code
     1 #include "stdafx.h"
     2 #include <iostream>
     3 using namespace std;
     4 
     5 int ComposeMoney(int Cycle)
     6 {
     7     if(Cycle%100!=0)
     8         throw exception("Cycle Is not Timesof 100!\n");
     9     int Sum=0;
    10     int cycle=Cycle/10;
    11     int Para1,Para2;
    12     int Temp;
    13     int t,h,k;
    14     for(k=0;k<=cycle;k++)
    15     {
    16         Para1=Cycle-10*k;
    17         Para2=k;
    18         t=Para2/10;h=Para2%10;
    19         Temp=5*t*t+1+4*t;
    20         if(1<=h&&h<=2) Temp+=h*t+h-1;
    21         else if(h>=3)   Temp+=h*t+h-2;
    22         Sum+=Temp* (Para1*Para1/20+1+2*Para1/5);
    23 
    24     }
    25     return Sum;
    26 }
    27 
    28 
    29 void Test()
    30 {
    31     try
    32     {
    33         int Sum=ComposeMoney(200)+ComposeMoney(100)+1;
    34         cout<<Sum<<endl;
    35     }
    36     catch(exception& e)
    37     {cout<<e.what();}
    38 }
    39 
    40 
    41 int _tmain(int argc, _TCHAR* argv[])
    42 {
    43     Test();
    44     return 0;
    45 }

    如果有什么错误的地方,麻烦周知我,谢谢。

  • 相关阅读:
    1-13Object类之toString方法
    jvm源码解读--16 锁_开头
    jvm源码解读--16 cas 用法解析
    jvm源码解读--15 oop对象详解
    jvm源码解读--14 defNewGeneration.cpp gc标记复制之后,进行空间清理
    jvm源码解读--13 gc_root中的栈中oop的mark 和copy 过程分析
    Error: Could not find or load main class ***
    使用javah 给.class类编译jni_helloworld.h文件头
    jvm源码解读--12 invokspecial指令的解读
    jvm源码解读--11 ldc指令的解读
  • 原文地址:https://www.cnblogs.com/cslave/p/2579689.html
Copyright © 2020-2023  润新知