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;
    }
    
    
  • 相关阅读:
    JS绑定种类汇总
    JS的块级作用域
    JS中的几种函数
    区分词法作用域(js)与动态作用域(精!)
    JS Dom节点操作demo!
    JS作用域相关知识(#精)
    js解析器(重要!)
    JS之鼠标在盒子中的位置
    JS之鼠标跟随
    JS之事件对象体验
  • 原文地址:https://www.cnblogs.com/kkkkahlua/p/7646240.html
Copyright © 2011-2022 走看看