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;
    }
    
    
  • 相关阅读:
    Hadoop源代码分析(五)
    使用Solr Data Import的deltaimport功能
    hbasewriter
    Hadoop源代码分析(四)
    lucene .NET 搜索图片 功能实现
    char类型与string类型的区别
    Windows程序设计:'SM_ MOUSEWHEELPRESENT' : undeclared identifier解决办法
    汇编里的栈空间
    在汇编源程序中,数据不能以字母开头
    中值
  • 原文地址:https://www.cnblogs.com/kkkkahlua/p/7646240.html
Copyright © 2011-2022 走看看