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

#include

#include

#include

#include

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;ifor(int j=0;jscanf("%d",&a[i][j]);

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

        }

    for(int i=0;ifor(int j=0;jfor(int u=0;u<=k;u++){

                 int k1;

                 if(i+11][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+11];

                     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;ifor(int j=0;j0][1])%mo;

    cout<return 0;

}

你可能感兴趣的:(动态规划(DP),Luogu)