思路:dp[i][j][k]表示在点(i,j)处能量的差值为k的方案数
转移的时候把差值取相反数就实现轮流了
代码如下:

1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #define MAX 480 5 #define mod 1000000007 6 using namespace std; 7 int dp[MAX][MAX][11]; 8 char str[MAX][MAX]; 9 int main(){ 10 int t,i,j,k,c=0,n,m,t1,t2,ans; 11 scanf("%d",&t); 12 while(t--){ 13 scanf("%d%d",&n,&m); 14 for(i=0;i<n;i++) 15 scanf("%s",&str[i]); 16 memset(dp,0,sizeof(dp)); 17 ans=0; 18 for(i=n-1;i>=0;i--) 19 for(j=m-1;j>=0;j--){ 20 for(k=0;k<11;k++){ 21 t1=(k+(str[i][j]-'0'))%11; 22 t2=(11-t1)%11; 23 if(i<n-1) dp[i][j][k]+=dp[i+1][j][t2]; 24 dp[i][j][k]%=mod; 25 if(j<m-1) dp[i][j][k]+=dp[i][j+1][t2]; 26 dp[i][j][k]%=mod; 27 if(t1==0){ 28 dp[i][j][k]++; 29 dp[i][j][k]%=mod; 30 } 31 if(k==0) ans=(ans+dp[i][j][0])%mod; 32 } 33 } 34 printf("Case %d: %d ",++c,ans); 35 } 36 return 0; 37 }