HDU 4558 剑侠情缘

来源:互联网 发布:t20天正建筑软件 编辑:程序博客网 时间:2024/05/16 00:48

题意:中文题不解释了。。。


思路: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 longconst 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;}