Luogu P1373 小a和uim之大逃离

题目描述传送门
一看这题首先想到设 d(i,j,k1,k2,0) 表示在小a刚吸完i,j这个位置的魔液,小a和uim的魔瓶的魔液量分别为k1,k2时的方案数, d(i,j,k1,k2,1) 表示在uim刚吸完……的方案数。
但是这样明显会爆内存…于是我就一直卡着了。后来看到讨论区有差这个字,才想到把状态减少到 d(i,j,k,0) d(i,j,k,1) 其中k为 小a的魔瓶量与uim的魔瓶量之差.
另外我用的是顺推,感觉更好想。
代码

#include<cstdio>

#include<iostream>

#include<cstring>

#include<algorithm>

#include<cstdlib>

using namespace std;

const int mo=1e9+7;

int n,m,k,d[800][800][16][2],a[800][800];

int main(){

    scanf("%d%d%d",&n,&m,&k);

    memset(d,0,sizeof(d));

    for(int i=0;i<n;i++)

        for(int j=0;j<m;j++){

            scanf("%d",&a[i][j]);

            d[i][j][a[i][j]][0]=1;

        }

    for(int i=0;i<n;i++)

        for(int j=0;j<m;j++)

            for(int u=0;u<=k;u++){

                 int k1;

                 if(i+1<n){

                     k1=u+a[i+1][j];

                     if(k1>k) k1-=(k+1);

                     d[i+1][j][k1][0]=(d[i+1][j][k1][0]+d[i][j][u][1])%mo;

                     k1=u-a[i+1][j];

                     if(k1<0) k1+=(k+1);

                     d[i+1][j][k1][1]=(d[i+1][j][k1][1]+d[i][j][u][0])%mo;

                 }

                 if(j+1<m){

                     k1=u+a[i][j+1];

                     if(k1>k) k1-=(k+1);

                     d[i][j+1][k1][0]=(d[i][j+1][k1][0]+d[i][j][u][1])%mo;

                     k1=u-a[i][j+1];

                     if(k1<0) k1+=(k+1);

                     d[i][j+1][k1][1]=(d[i][j+1][k1][1]+d[i][j][u][0])%mo;

                }

            }

    int ans=0;

    for(int i=0;i<n;i++)

        for(int j=0;j<m;j++)

            ans=(ans+d[i][j][0][1])%mo;

    cout<<ans<<endl;

    return 0;

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值