刷题dp小a和uim之大逃离
Posted xwww666666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了刷题dp小a和uim之大逃离相关的知识,希望对你有一定的参考价值。
地面上出现了一个n*m的巨幅矩阵,矩阵的每个格子上有一坨0~k不等量的魔液。
怪物各给了小a和uim一个魔瓶,说道,你们可以从矩阵的任一个格子开始,每次向右或向下走一步,从任一个格子结束。
开始时小a用魔瓶吸收地面上的魔液,下一步由uim吸收,如此交替下去,并且要求最后一步必须由uim吸收。
魔瓶只有k的容量,也就是说,如果装了k+1那么魔瓶会被清空成零,如果装了k+2就只剩下1,依次类推。
怪物还说道,最后谁的魔瓶装的魔液多,谁就能活下来。小a和uim感情深厚,情同手足,怎能忍心让小伙伴离自己而去呢?沉默片刻,小a灵机一动,如果他俩的魔瓶中魔液一样多,不就都能活下来了吗?小a和他的小伙伴都笑呆了!
将k+1,然后直接mod,得到的就是0-k
规定0操作为加,1操作为减,每次状态为两者的差
推出方程:
f[i][j][p][0]+=f[i-1][j][(p-mapp[i][j]+k)%k][1] (i-1>=1)
f[i][j][p][0]+=f[i][j-1][(p-mapp[i][j]+k)%k][1] (j-1>=1)
f[i][j][p][1]+=f[i-1][j][(p+mapp[i][j])%k][0] (i-1>=1)
f[i][j][p][1]+=f[i][j-1][(p+mapp[i][j])%k][0] (j-1>=1)
因为可以从任何状态开始,任何状态结束,所以从(1,1)->(n,m),
最后求(1,1)->(n,m)方案数总和
#include<cstdio> #include<cstdlib> using namespace std; int n,m,p,t; const int N=803,P=18,mod=1000000007; int d[N][N]; int f[N][N][P][2],ans;//0先手,1后手 int main() { scanf("%d%d%d",&n,&m,&p); p++; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&d[i][j]); f[i][j][d[i][j]%p][0]=1; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int k=0;k<p;k++) { if(j>1) f[i][j][k][1]=(f[i][j][k][1]+f[i][j-1][(k+d[i][j]+p)%p][0])%mod, f[i][j][k][0]=(f[i][j][k][0]+f[i][j-1][(k-d[i][j]+p)%p][1])%mod; if(i>1) f[i][j][k][1]=(f[i][j][k][1]+f[i-1][j][(k+d[i][j]+p)%p][0])%mod, f[i][j][k][0]=(f[i][j][k][0]+f[i-1][j][(k-d[i][j]+p)%p][1])%mod; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans=(ans+f[i][j][0][1])%mod; printf("%d ",ans); return 0; }
以上是关于刷题dp小a和uim之大逃离的主要内容,如果未能解决你的问题,请参考以下文章