zoukankan      html  css  js  c++  java
  • CF 375C Circling Round Treasures [DP(spfa) 状压 射线法]

    C - Circling Round Treasures

    题意:

    在一个$n*m$的地图上,有一些障碍,还有a个宝箱和b个炸弹。你从(sx,sy)出发,走四连通的格子。你需要走一条闭合的路径,可以自交,且围出来的复杂多边形内不能包含任何炸弹。
    你围出来的复杂多边形中包含的宝箱的价值和减去步数就是你的收益。
    求最大收益。$n,m le 20,a + b le 8$


    太坑了课件上的题意有问题一开始没说步数...

    后来改上然后$inq[][][]$最后没从$2$改成$S$然后我就看着玄学的$inq$好长时间

    和上题一样,只不过从一个点变成多个点,状压一下就好了、

    更新答案的时候枚举状态计算是否有炸弹和价值和

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int N=22,S=1<<8,M=N*N*S+5,INF=1e9;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,m,g[N][N],sx,sy,val[N];
    struct Object{
        int x,y,id;
        Object(int a=0,int b=0,int c=0):x(a),y(b),id(c){}
        bool operator <(const Object &r)const{return id<r.id;}
    }a[N];
    int p,t;
    int dx[4]={1,-1,0, 0},
        dy[4]={0, 0,1,-1};
    char s[N];
    int d[N][N][S];
    struct Grid{
        int x,y,s;
        Grid(int a=0,int b=0,int c=0):x(a),y(b),s(c){}
    }q[M];
    int head,tail,inq[N][N][S];
    inline void lop(int &x){if(x==M) x=1;}
    inline bool isInter(int a,int b,int x1,int y1,int x2,int y2){//1-->2 isInter (a,b)--right-->
        if(x1<a&&x2==a&&y2>b) return 1;
        if(x2<a&&x1==a&&y1>b) return 1;
        return 0;
    }
    int HandleInter(Grid u,Grid t){
        int s=u.s;
        for(int i=0;i<8;i++)
            s^= isInter(a[i].x , a[i].y , u.x , u.y , t.x , t.y)<<i;
        return s;
    }
    void spfa(){
        d[sx][sy][0]=0;
        head=tail=1;
        q[tail++]=Grid(sx,sy,0);inq[sx][sy][0]=1;
        while(head!=tail){
            Grid u=q[head++];lop(head);
            int x=u.x,y=u.y,s=u.s;//printf("
    now %d %d %d
    ",x,y,p);
            inq[x][y][s]=0;
            for(int i=0;i<4;i++){
                int nx=x+dx[i],ny=y+dy[i];
                if(nx<1||nx>m||ny<1||ny>n||g[nx][ny]) continue;
    
                Grid t(nx,ny);
                int ns=t.s=HandleInter(u,t);//printf("lok %d %d %d
    ",nx,ny,np);
                if(d[nx][ny][ns]>d[x][y][s]+1){//srintf("new %d %d %d
    ",nx,ny,ns);
                    d[nx][ny][ns]=d[x][y][s]+1;
                    if(!inq[nx][ny][ns])
                        q[tail++]=t,lop(tail),inq[nx][ny][ns]=1;
                }
            }
        }
        int ans=0;
        for(int i=0;i<S;i++) if(d[sx][sy][i]<INF){
            int _=0,bomb=0;
            for(int j=0;j<8;j++) if(i&(1<<j)){
                if(a[j].id==10) {bomb=1;continue;}
                else _+=val[j];
            }
            if(bomb) continue;
            ans=max(ans,_-d[sx][sy][i]);
        }
        printf("%d",ans);
    }
    int main(){
        //freopen("in","r",stdin);
        m=read();n=read();
        memset(d,127,sizeof(d));
        for(int i=1;i<=m;i++){
            scanf("%s",s+1);
            for(int j=1;j<=n;j++){
                g[i][j]=(s[j]!='.');
                if(s[j]=='S') g[i][j]=0,sx=i,sy=j;
                else if(s[j]=='B') a[p++]=Object(i,j,10);
                else if(s[j]>='0'&&s[j]<='9') a[p++]=Object(i,j,s[j]-'0'-1),t++;
            }
        }
        sort(a,a+p);
        for(int i=0;i<t;i++) val[i]=read();
        spfa();
    }
  • 相关阅读:
    static作用(1)
    Android开发之事件
    安卓开发之intent
    字符串去空
    字符串自实现(一)(mystrcpy,mystrcat,mystrcmp)
    Gin框架介绍及使用
    django model fake
    CentOS7 永久修改系统时间
    ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
    linux安装mysqlclient库
  • 原文地址:https://www.cnblogs.com/candy99/p/6502400.html
Copyright © 2011-2022 走看看