zoukankan      html  css  js  c++  java
  • 【26.87%】【codeforces 712D】Memory and Scores

    time limit per test2 seconds
    memory limit per test512 megabytes
    inputstandard input
    outputstandard output
    Memory and his friend Lexa are competing to get higher score in one popular computer game. Memory starts with score a and Lexa starts with score b. In a single turn, both Memory and Lexa get some integer in the range [ - k;k] (i.e. one integer among  - k,  - k + 1,  - k + 2, …,  - 2,  - 1, 0, 1, 2, …, k - 1, k) and add them to their current scores. The game has exactly t turns. Memory and Lexa, however, are not good at this game, so they both always get a random integer at their turn.

    Memory wonders how many possible games exist such that he ends with a strictly higher score than Lexa. Two games are considered to be different if in at least one turn at least one player gets different score. There are (2k + 1)2t games in total. Since the answer can be very large, you should print it modulo 109 + 7. Please solve this problem for Memory.

    Input
    The first and only line of input contains the four integers a, b, k, and t (1 ≤ a, b ≤ 100, 1 ≤ k ≤ 1000, 1 ≤ t ≤ 100) — the amount Memory and Lexa start with, the number k, and the number of turns respectively.

    Output
    Print the number of possible games satisfying the conditions modulo 1 000 000 007 (109 + 7) in one line.

    Examples
    input
    1 2 2 1
    output
    6
    input
    1 1 1 2
    output
    31
    input
    2 12 3 1
    output
    0
    Note
    In the first sample test, Memory starts with 1 and Lexa starts with 2. If Lexa picks  - 2, Memory can pick 0, 1, or 2 to win. If Lexa picks  - 1, Memory can pick 1 or 2 to win. If Lexa picks 0, Memory can pick 2 to win. If Lexa picks 1 or 2, Memory cannot win. Thus, there are 3 + 2 + 1 = 6 possible games in which Memory wins.

    【题解】

    题目要求的是最后两个人中甲的得分>乙的得分;
    可以换个角度理解问题;
    设甲相对于原来的分数增加的分数为x,乙相对于原来的分数增加的分数为y;
    则最后要甲的得分大于乙的得分;
    须满足x+a-b>y;
    其中a和b是甲和乙原来的分数;
    我们设f[i][j]表示i轮之后一个人相对于最初增加的分数为j的方案数:
    则f[i][j] = f[i-1][j-k]+f[i-1][j-k+1]+f[i-1][j-k+2]+…+f[i][j+k-1]+f[i][j+k];
    不要一个一个地加。在做的时候累加前缀和就好;
    最后枚举甲相对最初增加的得分j;
    然后枚举乙可以得到的分数范围;
    最后的到的f[i][j]数组是i轮,分数”增加”了-INF,-INF+1,…j的方案数;
    ans+= (f[t][j]-f[t][j-1])*f[t][j+a-b-1];
    因为下标不能为负数;
    所以整个数轴向右平移ZERO个单位;
    0就变成了ZERO = K*T+100;

    #include<cstdio>
    #include<algorithm>
    #include <iostream>
    #include<cstring>
    const int MAXT = 100;
    const int MAXK = 1000;
    const int MOD = 1000000007;
    const int ZERO = 100100;
    const int INF = 200200;
    using namespace std;
    
    long long f[MAXT + 10][MAXT*MAXK * 2 + 300],ans = 0;
    int a, b, t, k;
    
    void input(int &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
    }
    
    int main()
    {
        //freopen("F:\rush.txt", "r", stdin);
        input(a); input(b); input(k); input(t);
        int i, j;
        f[0][ZERO] = 1;//0回合一个都不选,增加的分数为0;
        for (i = 1; i <= t; i++)
        {
            for (j = 1; j <= INF; j++)//先获取前缀和
                f[i-1][j] = (f[i-1][j] + f[i-1][j - 1]) % MOD;
            for (j = 0; j <=INF; j++)
                f[i][j] = ((f[i - 1][min(INF, j + k)] - f[i - 1][max(j - k - 1, 0)])+MOD)%MOD;
            //右边是通过前缀和获取能够转移到这个状态的方案数;
            //f[i-1][j-k..j+k]这个范围;
        }
        for (j = 1; j <= INF; j++)//最后获取t轮的前缀和
            f[t][j] = (f[t][j] + f[t][j - 1]) % MOD;
        for (j = 0; j <= INF; j++)//枚举要赢的那个人"增加"的分数
        {
            int tt = min(INF, j + a - b - 1);//另一个人最大允许"增加"的分数
            if (tt<0)
                continue;
            else
            {
                long long temp = f[t][j] - f[t][j - 1];
                ans = (ans + (f[t][j] - f[t][j - 1]+MOD)*f[t][tt]) % MOD;
            }
        }
        printf("%I64d
    ", ans);
    }
  • 相关阅读:
    【算法学习笔记】27.动态规划 解题报告 SJTU OJ 1254 传手绢
    【算法学习笔记】26.扫描维护法 解题报告 SJTU OJ 1133 数星星
    【算法学习笔记】25.贪心法 均分纸牌问题的分析
    【算法学习笔记】24.记忆化搜索 解题报告 SJTU OJ 1002 二哥种花生
    【算法学习笔记】23.动态规划 解题报告 SJTU OJ 1280 整装待发
    【算法学习笔记】22.算法设计初步 二分查找 上下界判断
    【算法学习笔记】21.算法设计初步 求第k个数 划分法 快排法
    【算法学习笔记】20.算法设计初步 归并排序 求逆序数
    【算法学习笔记】19.算法设计初步 最大子列和问题的几种方法
    【算法学习笔记】18.暴力求解法06 隐式图搜索2 八数码问题 未启发
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632163.html
Copyright © 2011-2022 走看看