zoukankan      html  css  js  c++  java
  • [HG]小G坐电梯 题解

    C 小G坐电梯

    题目描述

    小G来到了著名的某大厦。大厦一共有n层,初始的时候小G在第 A 层。
    小G特别想去B层小 M 的办公室看一看,然而因为安保原因,B层已经被封锁无法进入。
    但是小G既然来了,就想在大厦里面逛一逛。大厦里面有一部电梯,小G决定坐 k 次电梯。
    因为小G比较无聊,他给自己设定了这样一个规矩:假如当前他在x层,则他要去的下一个楼层y和x的楼层差必须要小于 x 和 B 的楼层差,即 (|x−y| < |x−B|)
    每到达一个楼层,小G都要记录下来其楼层号。
    当小G转完一圈后,他也记录下了 (k + 1) 个楼层号(可能有重复)。
    小G现在 想知道,按照他定下的规矩,一共有多少种可能的楼层号序列?

    题解

    定义f[i][j][k]为当前走了i步,距离终点为j的,方向为k(0向下,1向上)。
    暴力DP+前缀和,滚动数组压掉一维。

    代码

    #include <cstdio>
    #include <cmath>
    
    using namespace std;
    
    #define max(a,b) ((a>b)?a:b)
    
    const int MOD = 1e9 + 7;
               //k     dlt  lft 0:dwn, 1:up
    long long f[10005][2];
    long long pre[20005][2];
    
    int mx_dlt, dlt;
    
    inline long long pls(long long a, long long b){
        return ((a + b >= MOD) ? (a + b - MOD) : (a + b));
    }
    
    inline void getPre(){
        pre[0][0] = pre[0][1] = 0;
        for (int j = 1; j <= mx_dlt; ++j){
            pre[j][0] = pls(pre[j - 1][0], f[j][0]);
            pre[j][1] = pls(pre[j - 1][1], f[j][1]);
        }
        for (int j = mx_dlt + 1; j <= mx_dlt * 2; ++j){ 
            pre[j][0] = pre[j - 1][0];
            pre[j][1] = pre[j - 1][1];
        }
    }
    
    int main(){
        freopen("lift.in", "r", stdin);
        freopen("lift.out", "w", stdout);
        int n, A, B, k; scanf("%d %d %d %d", &n, &A, &B, &k);
        mx_dlt = max(B * 2, abs(n - B) * 2); dlt = abs(A - B);
        f[dlt][0] = (A < B), f[dlt][1] = (A > B);
        getPre();
        for (int i = 1; i <= k; ++i){
            for (int j = 1; j <= mx_dlt; ++j){
                int tmp0 = f[j][0], tmp1 = f[j][1];
                if (B - j > 0)
                    f[j][0] = ((pre[mx_dlt][0] - pre[j / 2][0] - tmp0) % MOD + MOD) % MOD;
                if (B + j <= n)
                    f[j][1] = ((pre[mx_dlt][1] - pre[j / 2][1] - tmp1) % MOD + MOD) % MOD;
            }
            getPre();
        }
        long long ans = (pre[mx_dlt][0] + pre[mx_dlt][1] + MOD * 2) % MOD;
        printf("%lld", ans);
        return 0;
    }
    
  • 相关阅读:
    HDU5090模拟,hash
    在Android手机上获取其它应用的包名及版本
    ubunut在系统恢复模式下无法改动rootpassword的分析和解决
    Index column size too large. The maximum column size is 767 bytes.
    java实现定时任务
    APP账号密码传输安全分析
    用RSA加密实现Web登录密码加密传输
    svn is already locked解决方案
    ajax跨域请求
    redis+spring配置
  • 原文地址:https://www.cnblogs.com/linzhengmin/p/11761371.html
Copyright © 2011-2022 走看看