zoukankan      html  css  js  c++  java
  • POJ 1185 炮兵阵地

    题意:中文题……

    解法:状压dp。用二进制数表示一行的状态,1表示放人,0表示不放人,考虑dp[i][j][k]表示第i行状态为j,第i-1行状态为k时的人数,则有状态转移方程当状态枚举状态jkl分别表示第i行、第i-1行、第i-2行状态,当jkl互相兼容时,dp[i][j][k] = max(dp[i][j][k], dp[i - 1][k][l] + num[j]),num[i]表示状态i中的人数,状态一共有210个,所以复杂度为n×210×210×210,是不可以接受的,但因为每行里人之间的距离至少为2,所以合法的状态只有60,可以深搜得到,这样复杂度变为n×60×60×60。状态i和j兼容的条件为i&j等于0,即没有两个士兵站在同一列上,可以按同样的方法压缩地图的状态。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<string.h>
    #include<math.h>
    #include<limits.h>
    #include<time.h>
    #include<stdlib.h>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #include<iomanip>
    #define LL long long
    #define lson l, m, rt << 1
    #define rson m + 1, r, rt << 1 | 1
    
    using namespace std;
    
    char maze[110][15];
    int state[100];
    int tot = 0;
    int num[60];
    void dfs(int now, int pos, int ni)
    {
        num[tot] = ni;
        state[tot++] = now;
        for(int i = pos + 3; i < 10; i++)
        {
            int tmp = 1 << i;
            dfs(now | tmp, i, ni + 1);
        }
    }
    int dp[105][60][60];
    int M[105];
    int main()
    {
        dfs(0, -3, 0);
        int n, m;
        while(~scanf("%d%d", &n, &m))
        {
            memset(M, 0, sizeof M);
            for(int i = 1; i < n + 1; i++)
            {
                scanf("%s", maze[i]);
                for(int j = 0; j < 10; j++)
                {
                    M[i] <<= 1;
                    if(maze[i][j] != 'P') ++M[i];
                }
            }
            memset(dp, 0, sizeof dp);
            for(int i = 1; i < n + 1; i++)
            {
                for(int j = 0; j < 60; j++)
                {
                    for(int k = 0; k < 60; k++)
                    {
                        for(int l = 0; l < 60; l++)
                        {
                            if(state[l] & M[i]) continue;
                            if(state[j] & state[k]) continue;
                            if(state[j] & state[l]) continue;
                            if(state[k] & state[l]) continue;
                            dp[i][l][k] = max(dp[i][l][k], dp[i - 1][k][j] + num[l]);
                        }
                    }
                }
            }
            int ans = 0;
            for(int i = 0; i < 60; i++)
                for(int j = 0; j < 60; j++)
                    ans = max(dp[n][i][j], ans);
            printf("%d
    ", ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    Nginx负载均衡+代理+ssl+压力测试
    Nginx配置文件详解
    HDU ACM 1690 Bus System (SPFA)
    HDU ACM 1224 Free DIY Tour (SPFA)
    HDU ACM 1869 六度分离(Floyd)
    HDU ACM 2066 一个人的旅行
    HDU ACM 3790 最短路径问题
    HDU ACM 1879 继续畅通工程
    HDU ACM 1856 More is better(并查集)
    HDU ACM 1325 / POJ 1308 Is It A Tree?
  • 原文地址:https://www.cnblogs.com/Apro/p/4932282.html
Copyright © 2011-2022 走看看