题意:中文题不解释了。。。
思路:dp[x][y][dif][who] 表示 以坐标(x,y)为源点的所有方案数,其中dif表示人与剑的能量差值,who表示当前(x,y)这点,是选择人还是剑增长能量。总复杂度 500*500*10*2
代码:
//#pragma comment(linker, "/STACK:134217728,134217728") /*128Mb*/ //#pragma comment(linker,"/STACK:33554432") /*32Mb*/ //#pragma comment(linker,"/STACK:16777216") /*16Mb*/ #include <algorithm> #include <iostream> #include <string> #include <string.h> #include <stdio.h> #include <math.h> #include <stdlib.h> #include <vector> #include <queue> #include <stack> #include <cmath> #include <list> #include <set> #include <map> using namespace std; /*--in common define-----*/ #define N 500 #define E 100010 #define ll long long const int INF =0x3fffffff; const int PRIME =999983; const int MOD =1000000007; const int MULTI =1000000007; const double EPS=1e-8; /*--end in common define-*/ /*--in common use--------*/ #define CUBE(x) ((x)*(x)*(x)) #define SQ(x) ((x)*(x)) #define ALL(x) x.begin(),x.end() #define CLR(x,a) memset(x,a,sizeof(x)) inline bool isodd(int x){return x&1;} inline bool isodd(ll x) {return x&1;} /*--end in common use----*/ char s[N]; int g[N][N]; int dp[N][N][11][2]; int main() { int re,n,m,Case=1,ans; scanf("%d",&re); while(re--){ scanf("%d%d",&n,&m); ans=0; for(int i=0;i<n;i++){ scanf("%s",s); for(int j=0;j<m;j++) g[i][j]=s[j]-'0'; } CLR(dp,0); for(int i=0;i<n;i++){ for(int j=0;j<m;j++) for(int k=0;k<=10;k++){ dp[i][j][0][0]=dp[i][j][0][1]=1; } } for(int i=n-1,j=m-1;i>=0 && j>=0;i--,j--){ for(int x=i,y=j;y>=0;y--){ for(int k=0;k<=10;k++){ int v=g[x][y+1]; dp[x][y][k][1]+=dp[x][y+1][(k+v)%11][0]; dp[x][y][k][1]%=MOD; dp[x][y][k][0]+=dp[x][y+1][(k-v+11*10)%11][1]; dp[x][y][k][0]%=MOD; v=g[x+1][y]; dp[x][y][k][1]+=dp[x+1][y][(k+v)%11][0]; dp[x][y][k][1]%=MOD; dp[x][y][k][0]+=dp[x+1][y][(k-v+11*10)%11][1]; dp[x][y][k][0]%=MOD; } } for(int x=i-1,y=j;x>=0;x--){ for(int k=0;k<=10;k++){ int v=g[x][y+1]; dp[x][y][k][1]+=dp[x][y+1][(k+v)%11][0]; dp[x][y][k][1]%=MOD; dp[x][y][k][0]+=dp[x][y+1][(k-v+11*10)%11][1]; dp[x][y][k][0]%=MOD; v=g[x+1][y]; dp[x][y][k][1]+=dp[x+1][y][(k+v)%11][0]; dp[x][y][k][1]%=MOD; dp[x][y][k][0]+=dp[x+1][y][(k-v+11*10)%11][1]; dp[x][y][k][0]%=MOD; } } } for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ //printf("%d,%d..%d\n",i,j,dp[i][j][g[i][j]][0][0]); ans+=dp[i][j][g[i][j]][0]; ans%=MOD; } } printf("Case %d: %d\n",Case++,ans); } return 0; }