zoukankan      html  css  js  c++  java
  • 动态规划:HDU1248-钱币兑换问题

    解题心得:

    (青蛙跳台阶:有n阶台阶,青蛙可以一次跳一阶也可以一次跳两阶,问总共有多好中跳法)

    1、之前把这个问题的思路弄错了,以为是递推,就像青蛙跳台阶,用斐波那契求解。但是用斐波那契肯定会超范围。反过来想自己的思路其实是错的。青蛙跳台阶其实要区分顺序,比如三级台阶,先跳两级再跳一级和先跳两级再跳一级是两种不同的方法,但是钱币问题两分和一分都可以凑成三分钱但是不分先后顺序。

    2、凑硬币有三种算法,先说第一种。第一种就是完全背包问题,动态规划,一元的只有一种凑法,全是一元的,然后规划二元的,将两个一元的可以用一个一元的代换,所以可以代换一个一元的就多一种凑法,因为可以选择替换或者不替换,再逐步扩大钱数就可以了,三元的同上。

    3、第二种算法,和第一种比较相似,只不过先是凑的三元的,所以先看可以凑多少个三元的,n/3种不够的直接用一来填补就行了,n/3+1,+1部分就是全用一元的来组成的情况。然后就是逐步减去i个三元用二元来代替,思想方法同第二种,加起来就行了



    题目

    钱币兑换问题

    http://acm.hdu.edu.cn/showproblem.php?pid=1284

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 3261 Accepted Submission(s): 1842


    Problem Description
    在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法。请你编程序计算出共有多少种兑法。

    Input
    每行只有一个正整数N,N小于32768。

    Output
    对应每个输入,输出兑换方法数。

    Sample Input
    2934
    12553

    Sample Output
    718831
    13137761

    Author
    SmallBeer(CML)

    Source




    方法一:
    #include<stdio.h>
    #include<cstring>
    long long num[32770];
    int main()
    {
        memset(num,0,sizeof(num));
        num[0] = 1;
        for(int i=1;i<=3;i++)
            for(int j=i;j<=32768;j++)
                num[j] += num[j-i];
        int n;
        while(~scanf("%d",&n))
        {
            printf("%lld
    ",num[n]);
        }
    }
    方法二:
    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            long long sum = 0;
            sum = n/3 + 1;
            for(int i=0;i<=n/3;i++)
            {
                int t = (n-i*3)/2;
                sum += t;
            }
            printf("%lld
    ",sum);
        }
    }
    方法三:(母函数)
    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int c1[32770],c2[32770];
        int n;
        for(int i=0;i<=32768;i++)
        {
            c1[i] = 1;
            c2[i] = 0;
        }
        for(int i=2;i<=3;i++)
        {
            for(int j=0;j<=32768;j++)
            {
                for(int k=0;k+j<=32768;k+=i)
                {
                    c2[k+j] +=  c1[j];
                }
            }
            for(int k=0;k<=32768;k++)
            {
                c1[k] = c2[k];
                c2[k] = 0;
            }
        }
        while(~scanf("%d",&n))
        {
            printf("%d
    ",c1[n]);
        }
    }
    

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
  • 相关阅读:
    最近邻插值
    tp类型自动转换和自动完成
    tp读取器和写入器
    tp模型和数据库操作方法
    tp数据库操作
    tp请求和响应
    tp配置+路由+基本操作
    git的常见操作方法
    php 检查该数组有重复值
    公众号的TOKEN配置PHP代码
  • 原文地址:https://www.cnblogs.com/GoldenFingers/p/9107371.html
Copyright © 2011-2022 走看看