• bzoj1007: [HNOI2008]水平可见直线


    题目链接

    bzoj1007: [HNOI2008]水平可见直线

    题解

    显然,维护一个下凸壳(是这么叫吧)
    按斜率小及大排序
    引入直线a
    令直线a斜率小与等于直线b时
    令a挡住b
    那么a与b之前相交的直线c的交点必然在b与c交点的左边
    这样a与b的交点才会在直线c的左边
    用单调栈维护
    斜率与截距都相同时要unique...另外,有些卡精度.....

    代码

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    inline int read() {
        int x = 0,f = 1;
        char c = getchar();
        while(c < '0' || c > '9') {if(c == '-' ) f = -1;c = getchar();}
        while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
        return x * f;
    }
    const int maxn = 11; 
    int n,m;
    int D,val[maxn];
    int map[maxn][maxn],fs[6] = {1,0,-1,0,1} ; 
    char a[maxn];
    int dp[maxn][maxn][1 << maxn];
    int ans = 0;
    struct Node {
        int x,y,S;
        Node(int x = 0,int y = 0,int S = 0) : x (x),y(y),S(S) {}; 
    }loc[maxn * maxn];
    //inline int Get_Node(int i ,int j) { return i * (n - 1) + j; }
    int Get_Point(int x,int y,int tx,int ty,int S)  {
        for(int i = 0;i < D;++ i) {
            int X = loc[i].x,Y = loc[i].y;
            if(((x < X && tx >= X) || (x >= X && tx < X)) && y > Y) 
                S ^= (1<<i);
        }   
        return S;
    } 
    void spfa(int I,int J) {
        memset(dp,0x3f,sizeof dp); 
        std::queue<Node>que;que.push(Node(I,J,0)); 
        dp[I][J][0] = 0;
        while(! que.empty()) {
            Node cur = que.front();que.pop();
            for(int j = 0;j < 4;++ j) {
                int tx = cur.x + fs[j],
                    ty = cur.y + fs[j + 1];
                if(tx > n || tx < 1 || ty > m || ty < 1 || map[tx][ty] != -1) continue;
                int state = Get_Point(cur.x,cur.y,tx,ty,cur.S);   
                //printf("%d
    ",state);
                if(dp[tx][ty][state] > dp[cur.x][cur.y][cur.S] + 1) {
                    dp[tx][ty][state] = dp[cur.x][cur.y][cur.S] + 1;
                    que.push(Node(tx,ty,state)) ;
                }
            }
        }
        for(int i = 0;i < (1<<D); ++ i) {
            int V = -dp[I][J][i];
            for(int j = 0;j < D;++ j) {
                if((1 << j) & i) V += val[j];
            }
            ans = std::max(ans,V);
        }
    }
    int main() {
        n = read(),m = read();D = read();
        for(int i = 0;i < D;++ i) val[i] = read(); 
        for(int i = 1;i <= n;++ i) { 
            scanf("%s",a + 1);
            for(int j = 1;j <= m;++ j) {
                if(a[j] >= '0' && a[j] <= '9')  { map[i][j] = a[j] - '0' - 1;loc[map[i][j]] = Node(i,j,0); } 
                else if(a[j] == '#') map[i][j] = 13; 
                else map[i][j] = -1;
            } 
        }   
        for(int i = 1;i <= n;++ i) 
            for(int j = 1;j <= m;++ j) 
                if(map[i][j] == -1) spfa(i,j); 
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    車(rook)
    那些年,我们学过的文化课
    皇后(queen)
    蚂蚁运输(ant)
    [Z]CS权威会议
    [Z] 北大一牛人生物转申CS的经历
    TLS协议扫盲(握手,非对称加密,证书,电子签名等)
    关于SSE的一些资料
    Java下LDAP操作的资料
    [Z] Windbg以及vs debug使用
  • 原文地址:https://www.cnblogs.com/sssy/p/8969374.html
Copyright © 2020-2023  润新知