HDU 4558 剑侠情缘

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4558
题意:给出一个n*m的格子,每个格子有一个价值。在其中选择一条路径,路径中的一个格子a的下一个格子b,b只能在a的右侧或者下侧,这个路径上奇数格子的数字与偶数格子的数字之和相等时此路径为合法路径。有所有合法路径的个数。
思路:f[i][j][k][2],f[i][j][k][0]表示到达(i,j)格子,奇数格子与偶数格子的差值为k,且下一个为偶数格子,f[i] [j][k][1]表示到达(i,j)格子,奇数格子与偶数格子的差值为k,且下一个为奇数格子。转移时,从(i,j)向(i+1,j)和 (i,j+1),由0转向1,k减去那个格子的值;由1转向0,k加上那个格子的值。

 

char s[N][N];

int n,m;

int f[N][N][11][2];



void up(int &x,int y)

{

    x+=y;

    if(x>=mod) x-=mod;

}





int cal()

{

    clr(f,0);

    int i,j,k,x;

    FOR1(i,n) FOR1(j,m) s[i][j]-='0';

    FOR1(i,n) FOR1(j,m)

    {

        up(f[i][j][s[i][j]][0],1);

        FOR0(k,11)

        {

            if(i<n)

            {

                x=k+s[i+1][j];

                if(x>=11) x-=11;

                up(f[i+1][j][x][0],f[i][j][k][1]);





                x=k-s[i+1][j];

                if(x<0) x+=11;

                up(f[i+1][j][x][1],f[i][j][k][0]);

            }

            if(j<m)

            {

                x=k+s[i][j+1];

                if(x>=11) x-=11;

                up(f[i][j+1][x][0],f[i][j][k][1]);





                x=k-s[i][j+1];

                if(x<0) x+=11;

                up(f[i][j+1][x][1],f[i][j][k][0]);

            }

        }

    }



    int ans=0;

    FOR1(i,n) FOR1(j,m)

    {

        up(ans,f[i][j][0][0]);

        up(ans,f[i][j][0][1]);

    }

    return ans;

}





int main()

{

    int num=0;

    rush()

    {

        RD(n,m);

        int i,j,k;

        FOR1(i,n)  RD(s[i]+1);

        printf("Case %d: ",++num);

        PR(cal());

    }

}

 

 

 

你可能感兴趣的:(HDU)