首页 > 代码库 > BZOJ 1294 围豆豆Bean(DP)

BZOJ 1294 围豆豆Bean(DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1294

题意:

 

思路:f[i][j][st]表示从(i,j)出 发到(i,j)停止组成的回路、状态为st的最小步数。从每个0的位置(i,j)进行BFS一次,得到所有的状态。判断一个路径是否包含某个格子时,可以 从该格子向左发出一条射线,判断这条射线与路径交点个数。为奇数时包含。

 

char s[N][N];int f[N][N][1<<9];int a[N],n,m,K;int b[N][2];int dx[]={0,0,1,-1};int dy[]={1,-1,0,0};struct node{    int x,y,st;        node(){}    node(int _x,int _y,int _st)    {        x=_x;        y=_y;        st=_st;    }};int ok(int x,int y){    return x>=0&&x<n&&y>=0&y<m&&s[x][y]==‘0‘;}int get(int st,int x,int y,int xx){    int i;    FOR0(i,K)    {        if(y<b[i][1]&&(x==b[i][0]&&xx>b[i][0]||x>b[i][0]&&xx==b[i][0]))        {            st^=1<<i;        }    }    return st;}int cal(int x,int y){    clr(f,-1);    queue<node> Q;    Q.push(node(x,y,0)); f[x][y][0]=0;    int i,j,xx,yy,temp,st;    node p;    while(!Q.empty())    {        p=Q.front();        Q.pop();                FOR0(i,4)        {            xx=p.x+dx[i];            yy=p.y+dy[i];            if(!ok(xx,yy)) continue;            st=get(p.st,p.x,p.y,xx);            if(f[xx][yy][st]==-1)            {                f[xx][yy][st]=f[p.x][p.y][p.st]+1;                Q.push(node(xx,yy,st));            }        }    }    int ans=0;    FOR0(i,(1<<K)) if(f[x][y][i]!=-1)    {        temp=0;        FOR0(j,K) if(i&(1<<j)) temp+=a[j];        upMax(ans,temp-f[x][y][i]);    }    return ans;}int main(){    RD(n,m,K);    int i,j,k;    FOR0(i,K) RD(a[i]);    FOR0(i,n)    {        RD(s[i]);        FOR0(j,m) if(s[i][j]!=‘0‘&&s[i][j]!=‘#‘)        {            k=s[i][j]-‘1‘;            b[k][0]=i;            b[k][1]=j;        }    }    int ans=0;    FOR0(i,n) FOR0(j,m) if(s[i][j]==‘0‘) upMax(ans,cal(i,j));    PR(ans);}