• 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;
    }
    

      

  • 相关阅读:
    使用sequelize-auto生成sequelize的Models
    table中td内容过长自动换行
    编写一个方法,去掉数组的重复元素
    call, apply的用法意义以及区别是什么
    在javascript中使用媒体查询media query
    总结的一些封装好的javascript函数
    只对safari起作用的css hack
    javascrip实现无缝滚动
    Ensures there will be no 'console is undefined' errors
    jQuery.isEmptyObject()函数用于判断指定参数是否是一个空对象。
  • 原文地址:https://www.cnblogs.com/Apro/p/4932282.html
Copyright © 2020-2023  润新知