题意:中文题不解释了。。。
思路: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;
}