您的位置:首页 > 产品设计 > UI/UE

Luogu P1373 小a和uim之大逃离

2017-08-02 21:24 211 查看
题目描述传送门

一看这题首先想到设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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: