• 洛谷 P1373 小a和uim之大逃离 题解


    题面

    这道题好狗的说,数组开大一点会MLE掉,开少一点会RE掉~;

    下面是正解:

     我们设计状态:f[i][j][k][now]四维DP

     第一维和第二维(i,j)表示处于矩阵的(i,j)处(最后的结尾是(i,j));

     第三维k表示小A瓶中的值-小uim瓶中的值。(可以利用神奇的取模运算来使其是正数);(当然也可以用两个维度来分别表示他们瓶中的值)

     第四维now=1时表示到(i,j)轮到小uim来取了,然后结束游戏。now=0时表示在该点由小A结束游戏;

    由于只能往下和往右走,所以转移方程有2(结果)*2(方案)=4个

    f[i][j][k][0]=(f[i][j][k][0]+f[i-1][j][(k-a[i][j]+K)%K][1])%p;
    f[i][j][k][0]=(f[i][j][k][0]+f[i][j-1][(k-a[i][j]+K)%K][1])%p;
    f[i][j][k][1]=(f[i][j][k][1]+f[i-1][j][(k+a[i][j])%K][0])%p;
    f[i][j][k][1]=(f[i][j][k][1]+f[i][j-1][(k+a[i][j])%K][0])%p;

    注意取模时可能会溢出,处理好细节,用longlong一定会MLE掉;

    #include <bits/stdc++.h>
    using namespace std;
    int n,m,K;
    int a[801][801];
    int f[801][801][20][2];
    long long p=1000000007;
    int main ()
    {
        scanf("%d%d%d",&n,&m,&K);
        ++K;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%d",&a[i][j]);
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                f[i][j][a[i][j]%K][0]=1;
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                for(int k=0;k<=K;k++){
                    f[i][j][k][0]=(f[i][j][k][0]+f[i-1][j][(k-a[i][j]+K)%K][1])%p;
                    f[i][j][k][0]=(f[i][j][k][0]+f[i][j-1][(k-a[i][j]+K)%K][1])%p;
                    f[i][j][k][1]=(f[i][j][k][1]+f[i-1][j][(k+a[i][j])%K][0])%p;
                    f[i][j][k][1]=(f[i][j][k][1]+f[i][j-1][(k+a[i][j])%K][0])%p;
                }
            }
        }
        long long ans=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                ans=(ans+f[i][j][0][1])%p;
            }
        }
        cout<<ans;
    }
  • 相关阅读:
    图形合并
    启动脚本
    图形合并
    :(){:|:&};:
    C言语教程第八章:列举,位运算(5)
    C言语图形情势编程,赋性鼠标(4)
    C言语教程第十章:文件(6)
    C言语教程第十章:文件(4)
    红帽为什么要连结桌面Linux
    阶乘较劲争论器改善版
  • 原文地址:https://www.cnblogs.com/kamimxr/p/11346038.html
Copyright © 2020-2023  润新知