zoukankan      html  css  js  c++  java
  • Circling Round Treasures(codeforces 375c)

    题意:要求在一张网格图上走出一条闭合路径,不得将炸弹包围进去,使围出的总价值减去路径长度最大。

    /*
      类似于poj3182的做法,只不过出现了多个点,那么就用状态压缩的方法记录一个集合即可。 
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    using namespace std;
    char map[25][25],ch[25];
    int n,m,sx,sy,tx,ty,nx,ny,gx[10],gy[10],val[10],w[1010],dp[25][25][1010],cnt=-1,ans;
    int dx[4]={-1,1,0,0};
    int dy[4]={0,0,-1,1};
    struct node{int x,y,k;};
    bool ok(int j){
        if(nx==gx[j]&&ny<gy[j]){
            if(nx>tx)return true;
        }
        else if(tx==gx[j]&&ty<gy[j]){
            if(tx>nx)return true;
        }
        return false;
    }
    void bfs(){
        memset(dp,-1,sizeof(dp));
        queue<node> q;
        node u;u.x=sx;u.y=sy;u.k=0;q.push(u);dp[sx][sy][0]=0;
        while(!q.empty()){
            u=q.front();q.pop();nx=u.x;ny=u.y;int nk=u.k,tk;
            if(nx==sx&&ny==sy)ans=max(ans,w[nk]-dp[nx][ny][nk]);
            for(int i=0;i<4;i++){
                tx=nx+dx[i];ty=ny+dy[i];tk=nk;
                if(tx<1||tx>n||ty<1||ty>m||(map[tx][ty]!='.'&&map[tx][ty]!='S'))continue;
                for(int j=0;j<=cnt;j++)
                    if(ok(j))tk^=(1<<j);
                if(dp[tx][ty][tk]==-1){
                    dp[tx][ty][tk]=dp[nx][ny][nk]+1;
                    node v;v.x=tx;v.y=ty;v.k=tk;q.push(v);
                }
            }
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%s",ch);
            for(int j=1;j<=m;j++){
                map[i][j]=ch[j-1];
                if(map[i][j]=='S')sx=i,sy=j;
                if(map[i][j]>='1'&&map[i][j]<='8'){
                    int t=map[i][j]-'1';++cnt;
                    gx[t]=i;gy[t]=j;
                }
            }
        }
        for(int i=0;i<=cnt;i++)scanf("%d",&val[i]);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(map[i][j]=='B'){
                    ++cnt;gx[cnt]=i;gy[cnt]=j;val[cnt]=-10000;
                }
        for(int i=0;i<(1<<cnt+1);i++)
            for(int j=0;j<=cnt;j++)
                if(i&(1<<j))w[i]+=val[j];
        bfs();
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    进程与线程
    the art of seo(chapter seven)
    the art of seo(chapter six)
    the art of seo(chapter five)
    the art of seo(chapter four)
    the art of seo(chapter three)
    the art of seo(chapter two)
    the art of seo(chapter one)
    Sentinel Cluster流程分析
    Sentinel Core流程分析
  • 原文地址:https://www.cnblogs.com/harden/p/6391998.html
Copyright © 2011-2022 走看看