洛谷 P2233 [HNOI]公交车线路

洛谷

不知道大家做没做过传球游戏,这一题和传球游戏的转移方程几乎一样。

(A)(1)点,(E)(5)点,那么(f[i][j])代表第i步走到j的方案数。

[f[i][j]=f[i−1][j+1]+f[i−1][j−1] ]

因为题中给的是一个环,所以有几种情况。

[if(j==8)~f[i][j]=f[i−1][1]+f[i−1][7] ]

[if(j==1)~f[i][j]=f[i−1][8]+f[i−1][2] ]

还有,因为题中说,到了(E)点,就不会再动了。

[if(j==4)~f[i][j]=f[i−1][3] ]

[if(j==6)~f[i][j]=f[i−1][7] ]

边界很显然(f[0][1]=1)。但是我们注意这一题(n≤10^7),所以我们要滚动数组。

实际上我分析了一波,应该要用矩阵快速幂优化掉(n)那一维的,但是我交了一份递推代码上去也(A)了。

那么就不用管了,上代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int f[2][9]={},n,t=0;
    cin>>n;
    f[t][1]=1;
    for (int i=1;i<=n;++i) {
        t=!t;
        for (int j=1;j<=8;++j) {
            if (j==1) f[t][j]=f[!t][8]+f[!t][j+1];
            else if (j==8) f[t][j]=f[!t][j-1]+f[!t][1];
            else if (j==4) f[t][j]=f[!t][j-1];
            else if (j==6) f[t][j]=f[!t][j+1];
            else f[t][j]=f[!t][j-1]+f[!t][j+1];
            f[t][j]%=1000;
        }
    }
    cout<<f[t][5];
    return 0;
}
原文地址:https://www.cnblogs.com/fushao2yyj/p/9607822.html