Codeforces Round #274 (Div. 2)E. Riding in a Lift
2015-08-07 19:50
411 查看
题意:假设有n层电梯,现在你在x层,第d层是神奇的一层,因为你从第x层到第y层必须满足条件|x - y| < |x - b|,每走一步记下y,求走k步有多少种长度为k-1不同序列。
。。。过了蛮久再看此题有点陌生了。。。
有些题还是需要回顾一下,不然写了相当没写。
其实转态的转移题目已经说了,我们可以从当前点出发,在所有能从该点走到的点累加走到当前点的方案数,当然对于每一个当前点,我们去枚举所有的能到的点必然会超时,于是可以用前缀和的思想,假设当前点d(方案数为t)可以到达[x,y],我们先在sum【y】+=t;sun【x-1】-=t;这样不就是给区间【x,y】统一加上一个值吗,无需遍历该区间,然后因为是前缀合,从后到前遍历数组,我们通过sum数组求得更新后的第当前部每一点方案数。
第二种方案,逆推,我们求当前点y的方案数,可以从合法的上一步的x点推得而来,同样利用前缀和。
方案一:
。。。过了蛮久再看此题有点陌生了。。。
有些题还是需要回顾一下,不然写了相当没写。
其实转态的转移题目已经说了,我们可以从当前点出发,在所有能从该点走到的点累加走到当前点的方案数,当然对于每一个当前点,我们去枚举所有的能到的点必然会超时,于是可以用前缀和的思想,假设当前点d(方案数为t)可以到达[x,y],我们先在sum【y】+=t;sun【x-1】-=t;这样不就是给区间【x,y】统一加上一个值吗,无需遍历该区间,然后因为是前缀合,从后到前遍历数组,我们通过sum数组求得更新后的第当前部每一点方案数。
第二种方案,逆推,我们求当前点y的方案数,可以从合法的上一步的x点推得而来,同样利用前缀和。
方案一:
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; const int mod=1e9+7; long long f[5][5010]; long long s[5010]; int main() { int n,i,j,a,b,k,t; long long ans,tmp; while(scanf("%d%d%d%d",&n,&a,&b,&k)!=EOF) { ans=0; memset(f,0,sizeof(f)); f[0][a]=1; memset(s,0,sizeof(s)); if(b>a) { for(j=1;j<=k;j++){ for(i=b-1;i>=1;i--) { tmp=0; if(f[(j-1)%2][i]) { t=max(1,2*i-(b-1)); s[t-1]=(s[t-1]-f[(j-1)%2][i]+mod)%mod; s[i-1]=(s[i-1]+f[(j-1)%2][i])%mod; s[i]=(s[i]-f[(j-1)%2][i]+mod)%mod; s[b-1]=(s[b-1]+f[(j-1)%2][i])%mod; } } for(i=b-1;i>=1;i--) { tmp=(tmp+s[i])%mod; s[i]=0; f[(j)%2][i]=tmp; } } for(i=1;i<b;i++) ans=(ans+f[(j+1)%2][i])%mod; printf("%I64d\n",ans); } else { for(j=1;j<=k;j++){ for(i=n;i>b;i--) { tmp=0; if(f[(j-1)%2][i]) { t=min(n,2*i-(b+1)); s[t]=(s[t]+f[(j-1)%2][i])%mod; s[i]=(s[i]-f[(j-1)%2][i]+mod)%mod; s[i-1]=(s[i-1]+f[(j-1)%2][i]+mod)%mod; s[b]=(s[b]-f[(j-1)%2][i])%mod; } } for(i=n;i>=b+1;i--) { tmp=(s[i]+tmp)%mod; s[i]=0; f[j%2][i]=tmp; } } for(i=n;i>b;i--) ans=(ans+f[(j+1)%2][i])%mod; printf("%I64d\n",ans); } } }
方案二: 1 #include<bits/stdc++.h> #define mod 1000000007 using namespace std; int n,a,b,k,f[50010],p[50010],i,j; int main() { scanf("%d%d%d%d",&n,&a,&b,&k);f[a]=1; for(i=1;i<=k;i++) { for(j=1;j<=n;j++)p[j]=(p[j-1]+f[j])%mod; for(j=1;j<=n;j++) { if(j<b)f[j]=(p[(j+b-1)/2]-f[j]+mod)%mod; if(j>b)f[j]=((p -p[(j+b)/2]+mod)%mod-f[j]+mod)%mod; } } for(j=1;j<=n;j++)p[j]=(p[j-1]+f[j])%mod; printf("%d",p ); } 2 #include <stdio.h> #include <string.h> const int M=1000000007; int n,a,b,k,v[2][5432],*p=v[0],*q=v[1]; int main(){ scanf("%d%d%d%d",&n,&a,&b,&k); if(a>b)a=n-a+1,b=n-b+1; p[a]=1; for(int i=0;i<k;++i){ for(int j=1;j<b;++j)q[j]=M-p[j],(p[j]+=p[j-1])%=M; for(int j=1;j<b;++j)(q[j]+=p[(j+b-1)/2])%=M; int* w=p;p=q,q=w; } int s=0; for(int i=1;i<b;++i)(s+=p[i])%=M; printf("%d\n",s); }
相关文章推荐
- UVA-1068 Sum-1-N之间所有数的和
- 使用Material Design 应用主题
- POJ 2000 Gold Coins 简单模拟
- POJ-3299 Humidex-湿度温度露点
- DOM文档对象的简单介绍
- 使用Material Design 应用主题
- Eclipse工具条中添加下拉按钮
- 使用MySQL Workbench远程管理工具进行远程管理Mysql的错误及解决办法
- Atom飞行手册翻译: 4.4 Atom中的序列化
- 使用MySQL Workbench远程管理工具进行远程管理Mysql的错误及解决办法
- LeetCode(129) Sum Root to Leaf Numbers
- sendmail 发送html 的邮件
- MDK5 and STM32Cube
- POJ1505:Copying Books 解题心得
- Ubuntu 14.10 下Server版本中文乱码问题
- 杭电2149Public Sale
- 12.1 Image classification with deep learning常用模型
- 海量Web日志分析 用Hadoop提取KPI统计指标
- C++ 指针函数介绍
- jsoncpp详解