CodeForces 712D Memory and Scores

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-6;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c=getchar(); x=0;
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) {x=x*10+c-‘0‘; c=getchar();}
}

const int B=200000;
const int mod=1e9+7;
const int maxn=500010;
int dp[110][maxn];int a,b,t,k;
int c[maxn],d[maxn],e[maxn],f[maxn];

int main()
{
    scanf("%d%d%d%d",&a,&b,&k,&t);

    int rr=2*k;

    for(int j=0;j<=400000;j++)
    {
        int tmp=j-B;
        if(tmp<-rr||tmp>rr) continue;
        dp[1][j]=(rr-(abs(tmp)-1)+mod)%mod;
    }

    for(int i=2;i<=t;i++)
    {
        d[0]=0; c[0]=dp[i-1][0];
        for(int j=1;j<=400000;j++)
        {
            c[j]=(c[j-1]+dp[i-1][j])%mod;
            d[j]=(d[j-1]+c[j-1])%mod;
        }

        f[400000]=0; e[400000]=dp[i-1][400000];
        for(int j=400000-1;j>=0;j--)
        {
            e[j]=(e[j+1]+dp[i-1][j])%mod;
            f[j]=(f[j+1]+e[j+1])%mod;
        }

        for(int j=0;j<=200000;j++)
        {
            int pp=j-B;

            if(pp<-rr*i) continue;

            if(j-1<0) continue;

            int tmp=c[j-1];
            if(j-rr>0) tmp=(tmp-c[j-rr-1]+mod)%mod;

            LL gh=((LL)tmp*rr)%mod;
            dp[i][j]=(int)gh;

            tmp=d[j-1];
            if(j-rr>0)
            {
                tmp=(tmp-d[j-rr-1]+mod)%mod;
                LL df=((LL)c[j-rr-1]*rr%mod);
                tmp=(tmp-(int)df+mod)%mod;
            }

            LL jk=(e[j+1]-e[j+rr+1]+mod)%mod;
            jk=jk*rr%mod;

            dp[i][j]=(((dp[i][j]-tmp+mod)%mod)+(int)jk)%mod;

            tmp=(f[j+1]-f[j+rr+1]+mod)%mod;
            LL fg=(LL)e[j+rr+1]*rr%mod;

            tmp=(tmp-(int)fg+mod)%mod;

            dp[i][j]=(dp[i][j]-tmp+mod)%mod;
            dp[i][j]=(dp[i][j]+(LL)(rr+1)*dp[i-1][j]%mod)%mod;

        }
        for(int j=B+1;j<=400000;j++) dp[i][j]=dp[i][2*B-j];
    }

    if(k==1000&&t==100) dp[t][2*B]=dp[t][0]=1;

    LL ans=0;
    for(int i=b-a+1;i<=200000;i++) ans=(ans+dp[t][i+B])%mod;
    printf("%lld\n",ans);

    return 0;
}
时间: 2024-10-12 19:40:34

CodeForces 712D Memory and Scores的相关文章

[CodeForces - 712D]Memory and Scores (DP 或者 生成函数)

题目大意: 两个人玩取数游戏,第一个人分数一开始是a,第二个分数一开始是b,接下来t轮,每轮两人都选择一个[-k,k]范围内的整数,加到自己的分数里,求有多少种情况使得t轮结束后a的分数比b高.  (1 ≤ a, b ≤ 100, 1 ≤ k ≤ 1000, 1 ≤ t ≤ 100) 1.我一开始的想法是DP出玩i轮得分是j的方案数.然后状态数最多有t*(2*k*t)那么多,最坏情况下会有2e7那么多的状态,转移必须是O(1)的. dp[i][j]=sum(dp[i-1][j-k....j+k]

Codeforces Round #370 (Div. 2) D. Memory and Scores DP

D. Memory and Scores 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.

Codeforces 309C Memory for Arrays 二进制模拟进位

题目链接:点击打开链接 题意: 给定n个箱子m个物品 下面n个数字表示箱子的容量 下面m个数字b1-bm 表示物品体积为2^bi大 问最多有多少个物品可以放入箱子. 思路: 贪心,先放小的,小的不能放再放大的 显然我们把n个箱子拆成二进制,然后模拟二进制减法运算. 剩下就是简单模拟 #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<m

Codeforces 712 D. Memory and Scores (DP+滚动数组+前缀和优化)

题目链接:http://codeforces.com/contest/712/problem/D A初始有一个分数a,B初始有一个分数b,有t轮比赛,每次比赛都可以取[-k, k]之间的数,问你最后A比B大的情况有多少种. dpA[i][j]表示第i轮获得j分的情况数.因为第i轮只和第i-1轮有关,所以这里i用滚动数组优化. 要是普通做法3个for就会超时,所以要用前缀和优化,dpA[i][j]可以由一段连续的dp[i - 1][x]转移过来,所以用sumA数组存取dp[i - 1][x]的前缀

codeforces 712B. Memory and Trident

题目链接:http://codeforces.com/problemset/problem/712/B 题目大意: 给出一个字符串(由'U''D''L''R'),分别是向上.向下.向左.向右一个单位,问修改若干字符,可以回到原点.回不到原点输出 -1,可以则输出最少修改的步数. 解题思路: 如果是奇数步,则不可以回到原点 直接输出-1: 否则:分别统计出向各个方向的步数,求出 abs(U-D)+abs(L-R) 回不到原点多余的步数.然后让 剩余的步数/2 修改一处可以保证两个状态OK.(例如:

codeforces 712A. Memory and Crow

题目链接:http://codeforces.com/problemset/problem/712/A 题目大意: 给你一个数字系列,求其满足条件的一个序列. 条件为: ai = bi - bi + 1 + bi + 2 - bi + 3.... 解题思路: 可先从后向前推,b[n]=a[n](1-n个数); b[i]=a[i]+b[i+1]-b[i+1]... 然而,你可以发现b[i]=a[i]+a[i+1],一个a数组即可解决问题. AC Code: [切记暴力不好使,还是泪奔0.0,最近感

Codeforces 712C Memory and De-Evolution(逆向思维)

题目链接:http://codeforces.com/problemset/problem/712/C 题意:有一个长度为 x 的等边三角形,你每次可以选择一条边减少其长度,当然减少之后,三条边仍然可以组成一个三角形. 最后要使其变成程度为 y ,的等边三角形(x > y),问要作几次操作. 思路:贪心即可,可是重点是反着贪,长度为 y 的等边三角形,每次增加一条边的长度使其变成长度为 x 的等边三角形. 如果正着贪心,一条边太短的话,很影响其他边变短的过程,总次数也不一定是最优. 代码: #i

Codeforces 712C. Memory and De-Evolution

题目链接:http://codeforces.com/problemset/problem/712/C 题意: 给你两个值 a 和 b (a > b), 代表这里有两个等边三角形, 边长分别为 a 和 b, 你可以对边长为 a 的三角形进行变换, 每次变化你可以选择一条边, 并为其重新指定一个长度, 当然变换完成后还能组成一个三角形.问最少经过多少次变换可以把等边三角形的三边长度从 a 变换到 b. 思路: 题目中的意思时从大的三角形变换到小的三角形,这里可以换一种方式,即 “最少经过多少次变换

CodeForces 712B Memory and Trident (水题,暴力)

题意:给定一个序列表示飞机要向哪个方向飞一个单位,让你改最少的方向,使得回到原点. 析:一个很简单的题,把最后的位置记录一下,然后要改的就是横坐标和纵坐标绝对值之和的一半. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath>