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;
    }
  • 相关阅读:
    Meten Special Activities II
    Meten Special Activities II
    Meten Special Activities II
    Meten Special Activities II
    Meten Special Activities
    Meten Special Activities
    Meten Special Activities
    Meten Special Activities
    Meten Special Activities
    冒泡排序和选择排序
  • 原文地址:https://www.cnblogs.com/harden/p/6391998.html
Copyright © 2011-2022 走看看