买票找零问题
2013-10-28 10:28
232 查看
问题描述:
一场激烈足球赛即将开始,售票员紧张地卖票着……。 每张球票50元,现在有2n(1<=n<=18)个球迷排队购票,其中n个手持50元钞票,另外n个手持100元钞票。假设开始售票时售票处没有零钱可以找零。 问这2n个人有多少种排队方式,不至使售票处出现找不出零的局面? 例如当n=3时,共6人,3人持50元,3人持100元。可以找零的排队方式有如下5种: 50 50 50 100 100 100 50 50 100 100 50 100 50 50 100 50 100 100 50 100 50 50 100 100 50 100 50 100 50 100输入格式:
输入:输入n,表示2n个球迷,其中n个手持50元,另外n个手持100元。(n<=18)
输出格式:
输出:这2n个人可以找零的排队方式数。分析(动态规划):首先,2n肯定就是偶数(这是当然啦),而且第一个必须是50元。假设第一个50元和第K 个100元匹配(找零),第2个到第K-1个、第k+1个到第2n个也是可以实现找零的。其中,K-1-2+1、2n-(K+1)+1也必须是偶数,即K为偶数。假设,2n的排列个数为 f(2n) ,K=2i ( 1<= i <= n );则排列个数 f(2n)=sum{ f(2i-2)*f(2n-2i } ( 1<= i <= n ),其中f(0)=1;至此,递归公式就出来了。可以看出,上面的递归计算中存在子问题的重复计算问题,这就是符合动态规划的方法了。这里我们采用一中动态规划的变形-----备忘录方法。该方法的控制结构和递归一样(从顶向下),区别只是在递归过程中保存每个求解过的子问题,建立备忘录以备遇到重复问题时查看,避免相同子问题的重复求解。代码如下:
#include<iostream>using namespace std;int a[50];int func(int n){if(a>0) return a; //大于0,表示该子问题已计算过,直接返回结果for(int i=1;i<=n/2;i++){a+= func(2*i-2)*func(n-2*i); //递归调用计算}return a;}int abc (int n){a[0]=1; //f(0)=1for(int i=1;i<=n;i++)a[i]=0; //其他先置0return func(n);}int main(){int n;cin>>n;abc(2*n);cout<<a[2*n];return 0;}
相关文章推荐
- 笔试算法学习--买票找零问题(卡特兰数)
- 买票找零问题——卡特兰数的应用
- 从《编程之美》买票找零问题说起,娓娓道来卡特兰数——兼爬坑指南
- 从《编程之美》买票找零问题说起,娓娓道来卡特兰数——兼爬坑指南
- 从《编程之美》买票找零问题说起,娓娓道来卡特兰数——兼爬坑指南
- 从《编程之美》买票找零问题说起,娓娓道来卡特兰数——兼爬坑指南
- LeetCode c语言-Generate Parentheses和买票找零问题
- 从《编程之美》买票找零问题说起,娓娓道来卡特兰数——兼爬坑指南
- 从《编程之美》买票找零问题说起,娓娓道来卡特兰数——兼爬坑指南
- 关于《编程之美》的4.3 买票找零问题
- POJ 3260 The Fewest Coins(多重背包问题, 找零问题, 二次DP)
- python 回溯法 子集树模板 系列 —— 17、找零问题
- 动态规划算法求解硬币找零问题(Java)
- 找零问题
- 递归找零问题
- 人民币找零 vs 硬币问题 贪心 vs 动态规划
- 动态规划求解硬币找零问题——Java实现
- FZU 2029 买票问题
- 贪心算法实例(二):钱币找零问题
- 关于背包的硬币找零问题