动态规划:排队买票问题

该博客讨论了一种使用动态规划解决球赛售票找零钱问题的方法。当m个人持50元钞票,n个人持100元钞票时,如何排列队伍使得售票处不会出现无法找零的情况。通过递推公式f[m][n]=f[m-1][n]+f[m][n-1]计算不同排队组合,并初始化特定边界条件,如f[i][0]=1和当m<n时f[m][n]=0。代码实现中使用二维数组dp存储这些组合,并输出最终答案f[m][n]。
摘要由CSDN通过智能技术生成

问题描述
一场球赛开始前,售票工作正在紧张进行中。每张球票为50元,有m+n个人排队等待购票,其中有m 个人手持50元的钞票,另外n个人手持100元的钞票。求出这m+n个人排队购票,使售票处不至出现找不开钱的局面的不同排队种数 。(约定:开始售票时售票处没有零钱;拿同样面值钞票的人对换位置为同一种排队。)

分析:这题可以用递归或者递推(动态规划)来解决,在数据大且要求多组输入的情况下,递推提前打表是便捷且快速的。用数组dp[i][j]表示有i个拿50元票的人和j个拿100元票的人的排队方案。
①假设此时n=0,即没有人拿100块去买票,很显然,剩余的人怎么排都只有一种情况,即f[i][0]=1。
②假设m<n,即拿50张票的人的数量不如拿100张票的人数,很显然任何方案都会出现找不开钱的局面,此时f[m][n]=0。
③其他情况下,就要用到动态规划的思想了:
假如排队的最后一个人是手里拿着100元票的,那么这个情况下排队方案数相当于前m+n-1个人(m个手拿50元,n-1个手拿100元)的排队方案数,即f[m][n-1]。
假如排队的最后一个人手里拿着50元票,那么此时排队方案数为f[m-1][n]。
所以第三种情况下,f[m][n]=f[m-1][n]+f[m][n-1];

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=55;
ll f[maxn][maxn];
void solve(){
    for(int i=1;i<=maxn;++i)f[i][0]=1;
    for(int i=0;i<maxn-1;++i)
        for(int j=i+1;j<maxn;++j)f[i][j]=0;
    for(int i=1;i<=maxn;++i)
        for(int j=1;j<=i;++j)
            f[i][j]=f[i-1][j]+f[i][j-1];
}
int main(){
    int m,n;
    solve();
    while(~scanf("%d%d",&m,&n)){
        printf("%lld\n",f[m][n]);
    }
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

布布要成为最负责的男人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值