嘘~ 正在从服务器偷取页面 . . .

洛谷P2233 [HNOI2002]公交车路线 题解


洛谷P2233 [HNOI2002]公交车路线 题解

题目链接:P2233 [HNOI2002]公交车路线

题意

在幻想郷新建的环城公路上一共有 $8$ 个公交站,分别为 A、B、C、D、E、F、G、H。

公共汽车只能够在相邻的两个公交站之间运行,因此你从某一个公交站到另外一个公交站往往要换几次车,例如从公交站 $A$ 到公交站 $D$,你就至少需要换 $3$ 次车。

不过琪露诺的方向感极其糟糕,我们知道从公交站 $A$ 到公交 $E$ 只需要换 $4$ 次车就可以到达,而她却总共换了 $n$ 次车!

注意琪露诺一旦到达公交站 $E$,她不会笨到再去换车。现在希望你计算一下琪露诺有多少种可能的乘车方案。

输入格式

仅有一个正整数 $n$,表示琪露诺从公交车站 A 到公交车站 E 共换了 $n$ 次车。

输出格式

输出一个正整数表示方案数,由于方案数很大,请输出方案数除以 $1000$ 后的余数。

数据范围

$4\le n\le10^7$。

首先从 $E$ 断环为链,因为走到 $E$ 以后不会再换车。

此时的公交线路就关于 $A$ 对称了,容易发现相对称的两个站点方案数是相同的。

故我们只对 $A \sim D$ 做一遍dp。设 $f_{i,j}$ 表示走了 $i$ 步到 $j$ 的方案数,则有

稍微滚滚数组就好啦,时间复杂度 $\mathcal{O}(n)$ ,代码如下:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
void up(int &x,int y) { x < y ? x = y : 0; }
void down(int &x,int y) { x > y ? x = y : 0; }
const int mod = 1000;
#define N ((int)())

int n,p,f[2][4];
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    // freopen("check.in","r",stdin);
    // freopen("check.out","w",stdout);
    cin >> n; p = 1; f[0][0] = 1;
    for(int k = 1; k < n; k++, p ^= 1)
    {
        f[p][0] = 2 * f[p ^ 1][1] % mod;
        f[p][1] = (f[p ^ 1][0] + f[p ^ 1][2]) % mod;
        f[p][2] = (f[p ^ 1][1] + f[p ^ 1][3]) % mod;
        f[p][3] = f[p ^ 1][2] % mod;
    }
    cout << 2 * f[p ^ 1][3] % mod << '\n';
    return 0;
}

文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
  目录