ACM学习历程—NPU 2015年陕西省程序设计竞赛网络预赛(正式赛)F题 和谐的比赛(递推)

Description

今天西工大举办了一场比赛总共有m+n人,但是有m人比较懒没带电脑,另外的n个人带了电脑。不幸的是,今天机房的电脑全坏了只能用带的电脑,一台电脑最多两人公用,确保n>=m。但是大家来的时间不同,随机次序来机房,带电脑的人直接准备比赛而没带电脑的人需要向带电脑并还没和别人公用的人求助(当然会答应)。但是,如果不存在带电脑并还没和别人公用的人,那他就要等了,等是很让人头疼的,这就不和谐了,当然假如没有这样的情况发生比赛是很和谐的。

Input

输入多组数据,每组数据只有一行m(1<=m<=n<=20)和n(1<=n<=20);

Output

输出和谐比赛的场数。

Sample Input

1 2
3 8
4 17

Sample Output

2
110 
4655

题目大意就是顺序中没带电脑的人永远大于带电脑的人的所有情况一共有多少种。

此题之前做过类似的,和找零的题目一样。

就是对最后一个人讨论。不妨设带电脑的人为1,不带的为0。设f(i, j)表示i个人不带电脑,j个人带了电脑的总数。

如果最后一个人是1,自然前面的就是f(i, j-1)

如果最后一个人是0,自然前面的就是f(i-1, j)

然后把所有 i > j的都置零。就可以求和了。此外就是先对所有的f(1, i)赋值为i,这样有边界才能递推。(这种情况想一想就出来了)

可能有人会想这两种情况满足条件不?对于最后一个是1,前面随便满足自然整体满足了。对于最后一个是0的,首先i < j是肯定的,自然前面满足整体可能是满足的。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>
#define LL long long

using namespace std;

int n, m;
LL f[25][25];

void Init()
{
    memset(f, 0, sizeof(f));
    for (int i = 1; i <= 20; ++i)
    {
        f[1][i] = i;
    }
    for (int i = 2; i <= 20; ++i)
    {
        for (int j = i; j <= 20; ++j)
            f[i][j] = f[i-1][j] + f[i][j-1];
    }
}

int main()
{
    //freopen("test.in", "r", stdin);
    while (scanf("%d%d", &m, &n) != EOF)
    {
        Init();
        printf("%lld
", f[m][n]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/andyqsmart/p/4508558.html