zoukankan      html  css  js  c++  java
  • Atcoder CODE FESTIVAL 2017 qual B E

    题目链接

    题意

    (A+B)个球排成一行,左边(A)个为红球,右边(B)个为蓝球。

    最开始可以选择两个数(s,t),每次操作可以取左起第(1)(s)(t)个球。问有多少种不同的取球序列。

    Sample

    Sample Input 1

    3 3

    Sample Output 1

    20

    Explanation

    There are 20 ways to give 3 red balls and 3 blue balls. It turns out that all of them are possible.

    Here is an example of the operation (r stands for red, b stands for blue):

    You choose s=3,t=4.
    Initially, the row looks like rrrbbb.
    You remove 3rd ball (r) and give it to Snuke. Now the row looks like rrbbb.
    You remove 4th ball (b) and give it to Snuke. Now the row looks like rrbb.
    You remove 1st ball (r) and give it to Snuke. Now the row looks like rbb.
    You remove 3rd ball (b) and give it to Snuke. Now the row looks like rb.
    You remove 1st ball (r) and give it to Snuke. Now the row looks like b.
    You remove 1st ball (b) and give it to Snuke. Now the row is empty.
    This way, Snuke receives balls in the order rbrbrb.

    思路

    官方题解

    将剩下的球的序列转化成二维平面上的点,则取球过程为起点为((A,B)),终点为((0,0))的路径。

    显然,可以一直向左走,因为向左走就对应着取该序列的第一个元素;

    但是向下走是需要满足一定的条件的,那就是红球的个数小于(s)(t)中的某一个。

    在阴影区域内可以随意向左走或向下走。

    因此,可以枚举((p,q)),从((A,B))((p,q))的路径条数可以通过预处理组合数然后(O(1))算出,而从((p,q))((0,0))的路径条数可以预处理出。

    (q-1=4)为例,

    分界线为(x=0)时,有(inom{4}{0})种,
    分界线为(x=1)时,有(inom{4}{0}+inom{4}{1})种,
    分界线为(x=2)时,有(inom{4}{0}+inom{4}{1}+inom{4}{2})种,
    分界线为(x=3)时,有(inom{4}{0}+inom{4}{1}+inom{4}{2}+inom{4}{3})种,
    分界线为(x=4)时,有(inom{4}{0}+inom{4}{1}+inom{4}{2}+inom{4}{3}+inom{4}{4})种,
    分界线为(x=5)时,有(inom{4}{0}+inom{4}{1}+inom{4}{2}+inom{4}{3}+inom{4}{4})种,
    ……
    分界线为(x=n(ngeq 4))时,有(inom{4}{0}+inom{4}{1}+inom{4}{2}+inom{4}{3}+inom{4}{4})种.
    对于((p,q)),将分界线为(x=0,1,2,...,p)的情况累和,即得路径条数。

    Code

    参考:

    #include <bits/stdc++.h>
    #define maxn 4000
    #define maxm maxn+10
    using namespace std;
    typedef long long LL;
    LL temp[maxm][maxm], C[maxm][maxm];
    const LL mod = 1e9+7;
    LL add(LL a, LL b) { return (a+b) % mod; }
    LL mul(LL a, LL b) { return (a*b) % mod; }
    void init() {
        for (int i = 0; i <= maxn; ++i) C[i][0] = 1;
        for (int i = 1; i <= maxn; ++i) {
            for (int j = 1; j <= i; ++j) C[i][j] = add(C[i-1][j], C[i-1][j-1]);
        }
        for (int i = 0; i <= maxn; ++i) {
            temp[i][0] = C[i][0];
            for (int j = 1; j <= maxn; ++j) {
                temp[i][j] = add(temp[i][j-1], C[i][j]);
            }
        }
        for (int i = 0; i <= maxn; ++i) {
            for (int j = 1; j <= maxn; ++j) temp[i][j] = add(temp[i][j], temp[i][j-1]);
        }
    }
    int main() {
        init();
        int a, b;
        LL ans = 0;
        scanf("%d%d", &a, &b);
        for (int p = 0; p <= a; ++p) {
            for (int q = 0; q <= b-1; ++q) {
                if (p+q > a) continue;
                if (q == 0) ans = add(ans, 1);
                else ans = add(ans, mul(C[b-1][q], temp[q-1][p]));
            }
        }
        printf("%lld
    ", ans);
        return 0;
    }
    
    
  • 相关阅读:
    CentOS7.5右键创建空白文档
    CentOS7.5安装配置conky(极简)
    CentOS7.5安装nodejs
    CentOS7.5安装网易云音乐
    CentOS7.5删除旧的内核
    CentOS7.5安装notepadqq
    CentOS7英文环境下使用中文输入法
    CentOS7安装Pycharm后无法使用日常的快捷键
    tomcat的work目录作用
    ORACLE获取某个时间段之间的月份列表
  • 原文地址:https://www.cnblogs.com/kkkkahlua/p/7646240.html
Copyright © 2011-2022 走看看