0
点赞
收藏
分享

微信扫一扫

洛谷P1754 球迷购票问题【DP】

hoohack 2022-01-14 阅读 27

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

思路:
f [ i ] [ j ] f[i][j] f[i][j]:前 i i i个人中有 j j j个人给的50情况下能找零的方案数。
状态转移:
①第 i i i个人给的是50: f [ i ] [ j ] + = f [ i − 1 ] [ j − 1 ] 【 i > = 1 ∧ j > = 1 】 f[i][j]+=f[i-1][j-1]【i>=1 \wedge j>=1】 f[i][j]+=f[i1][j1]i>=1j>=1,即多了一张50。
②第 i i i个人给的是100: f [ i ] [ j ] + = f [ i − 1 ] [ j + 1 ] 【 i > = 1 ∧ j > = 1 ∧ j + 1 < = i − 1 】 f[i][j]+=f[i-1][j+1]【i>=1 \wedge j>=1 \wedge j+1<=i-1】 f[i][j]+=f[i1][j+1]i>=1j>=1j+1<=i1,即给了100找50,自己少了张50。
此外注意初始状态 f [ 0 ] [ 0 ] = 1 f[0][0]=1 f[0][0]=1,因为一个人都没有也是一种方案。而且因为只有 2 × n 2×n 2×n个人,因此终止状态一定是50都找完了,因此对应 2 × n 2×n 2×n处没有零钱的状态,即 f [ 2 × n ] [ 0 ] f[2×n][0] f[2×n][0]
代码如下:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 55;
typedef long long LL;
LL a[N],f[N][N];
int main()
{
    LL n,ans=0;cin>>n;
    f[0][0]=1;
    for(int i=1;i<=2*n;i++)
        for(int j=0;j<=i;j++)
        {
            if(j-1>=0) f[i][j]+=f[i-1][j-1];
            if(j+1<=i-1) f[i][j]+=f[i-1][j+1];
        }
    cout<<f[2*n][0];
    return 0;
}
举报

相关推荐

0 条评论