CodeForces 375C

http://blog.csdn.net/qq574857122/article/details/17797639?locationNum=2&fps=1

状压+最短路
判断一个点在不在路径内,选择一个方向数边的条数,判断奇偶性就好了

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define rep(i,n) for (int i=0;i<n;++i)
const int u[]={1,0,-1,0},v[]={0,1,0,-1};
int n,m,sx,sy,ans,T,B,p[1<<8],price[9],c[22][22],d[22][22][1<<8],f[200000],g[200000],e[200000];
char s[22][22];
int main()
{
    scanf("%d%d",&n,&m);
    rep(i,n){
        scanf("%s",s[i]);
        rep(j,m) if (s[i][j]=='S') sx=i,sy=j,s[i][j]='.';
        rep(j,m) if (s[i][j]>'0' && s[i][j]<'9'){++T; rep(k,i) c[k][j]|=1<<(s[i][j]-49);}
    }
    rep(i,T) scanf("%d",price+i); B=T;
    rep(i,1<<T) rep(j,T) if (i>>j&1) p[i]+=price[j];
    rep(i,n) rep(j,m) if (s[i][j]=='B'){rep(k,i) c[k][j]|=1<<B; ++B;}
    int h=0,t=1; f[1]=sx,g[1]=sy,e[1]=0; memset(d,6,sizeof(d)); d[sx][sy][0]=0;
    while (h<t){
        int x=f[++h],y=g[h],z=e[h],D=d[x][y][z];
        rep(dir,4){
            int i=x+u[dir],j=y+v[dir],k=z;
            if (i<0 || i>=n || j<0 || j>=m || s[i][j]!='.') continue;
            if (y!=j) k^=c[i][min(y,j)];
            if (D+1<d[i][j][k]) d[i][j][k]=D+1,f[++t]=i,g[t]=j,e[t]=k;
        }
    }
    rep(i,1<<T) ans=max(ans,p[i]-d[sx][sy][i]);
    printf("%d\n",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值