电梯
问题描述
无所事事的Cinzo决定用坐电梯的方式来打发时间。他住在一个N层的房子中,最底下为1层,最高处为N层。他从他家所在的第A层出发,并决定连续坐K次电梯。
但由于迷信的缘故,B在中国被视为是不幸运的,所以整座楼并没有第B层。也是因为这个原因,如果Cinzo想从第X层出发到达第Y层,他希望Y能满足|X - Y| < |X - B|。
每次电梯到达后,Cinzo都会将电梯所到的层数记录在小本子上;K次电梯都坐完后,他将得到一个长度为K的数列。现在,Cinzo想知道,他可能写出多少个不同的数列?
输入格式(lift.in)
一行四个整数,N,A,B,K,分别代表电梯的层数,Cinzo最初的位置,不幸运的层数,以及乘坐电梯的次数。
输出格式(lift.out)
一个整数,代表不同的数列数。(结果对1000,000,007取模)
样例输入
5 2 4 2
样例输出
2
数据范围与约束
对于20%的数据,N<=10, K<=5;
对于60%的数据,N,K<=100;
对于100%的数据,N,K<=5000。
思路:
优化的dp。为什么可以优化那?
时间上的优化:因为每一次递推改变的是一个范围内的值,所以能用差值维护。
空间上的优化:每一步仅与他的上一步有关,能用滚动数组。
#include<iostream> #include<queue> #include<math.h> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define M 1000000007 #define LL long long int n,a,b,k; LL f[2][5005],ans; int l[5005],r[5005]; int main() { freopen("lift.in", "r", stdin); freopen("lift.out", "w", stdout); scanf("%d%d%d%d",&n,&a,&b,&k); f[0][a]=1; int e=0,g=1; for(int i=1;i<=n;i++) { int dis=abs(i-b); l[i]=max(1,i-dis+1); r[i]=min(n,i+dis-1); } for(int i=1;i<=k;i++) { for(int j=1;j<=n;j++) f[g][j]=0; for(int j=1;j<=n;j++) (f[g][l[j]]+=f[e][j])%=M,(f[g][r[j]+1]-=f[e][j])%=M; for(int j=1;j<=n;j++) (f[g][j]+=f[g][j-1])%=M; for(int j=1;j<=n;j++) f[g][j]-=f[e][j]; swap(e,g); } for(int j=1;j<=n;j++) (ans+=f[e][j])%=M; ans=(ans+M)%M; cout<<ans; return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 上周热点回顾(1.20-1.26)
· 【译】.NET 升级助手现在支持升级到集中式包管理