P1754

球迷购票问题

题意描述

盛况空前的足球赛即将举行。球赛门票售票处排起了球迷购票长龙。
按售票处规定,每位购票者限购一张门票,且每张票售价为50元。在排成长龙的球迷中有N个人手持面值50元的钱币,另有N个人手持面值100元的钱币。假设售票处在开始售票时没有零钱。试问这2N个球迷有多少种排队方式可使售票处不致出现找不出钱的尴尬局面。

输入

2

输出

2

点拨

线性dp,dp[x][y]表示考虑前x个位置,恰好有m张50元可以找给别人
所以递推方程就是dp[x][y] = dp[x-1][y-1] + dp[x-1][y+1]
初始化dp[1][1] = 1;
顺便提一下这里还可以优化空间为一维,感兴趣的朋友可以试试

代码

#include<iostream>
#include<utility>
using namespace std;
typedef long long ll;
#define fi(i,a,b) for(int i = a; i <= b; ++i)
#define fr(i,a,b) for(int i = a; i >= b; --i)
#define x first
#define y second
#define sz(x) ((int)(x).size())
#define pb push_back
using pii = pair<int,int>;
//#define DEBUG
#define int long long
int dp[45][25];
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
#ifdef DEBUG
    //freopen(D:\in.txt,r,stdin);
#endif
    int n;
    cin >> n;
    dp[1][1] = 1;
    fi(i,2,2*n){
        fi(j,0,i){
            dp[i][j] = dp[i-1][j+1];
            if( j >= 1)
                dp[i][j] += dp[i-1][j-1];
        }
    }
    cout << dp[2*n][0] << endl;
    return 0;
}
posted @ 2022-03-22 11:57  Sun-Wind  阅读(21)  评论(0编辑  收藏  举报