zoukankan      html  css  js  c++  java
  • 状压dp:luogu P2704 [NOI2001]炮兵阵地

    https://www.luogu.org/problemnew/show/P2704

    知识点:1.滚动数组:取模实现

                   2.位运算优先级最低

                 顾是if(!(a&b))而不是if(!a&b)

    code: 

    #include <bits/stdc++.h>
    #define N 101
    #define M 10
    using namespace std;
    int n,m;
    int tot = 0;
    int dp[4][1000][1000],mp[N],state[1000];
    int val[1000];
    int check(int k)
    {
         if(((k&(k<<1))==0)&&((k&(k<<2))==0)&&((k&(k>>1))==0)&&((k&(k>>2))==0))return 1;
         else return 0;
    }
    int get(int k)
    {
        int ans = 0;
        for(int i = 0;i < m;i++)
        {
            if(k&(1 << i))ans++;
        }
        return ans;
    }
    char ch[N];
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i++)
        {
            scanf("%s",ch);
            for(int j = 0;j < m;j++)
            {
                if(ch[j] == 'H')
                {
                    mp[i] = mp[i]|(1 << j);
                }
            }
        }
        for(int i = 0;i <= (1 << m) - 1;i++)
        {
            if(check(i))
            {
                state[++tot] = i;   
                val[tot] = get(i);
                dp[1][0][tot] = val[tot];
            }
        }
        for(int i = 1;i <= tot;i++)
        {
            for(int j = 1;j <= tot;j++)
            {
                if((state[i]&state[j]) == 0&&(state[i]&mp[2]) == 0)
                dp[2][j][i] = max(dp[2][j][i],dp[1][0][j] + val[i]);
            }
        }
        for(int i = 3;i <= n;i++)
        {
            for(int j = 1;j <= tot;j++)
            if((state[j]&mp[i]) == 0)
            for(int k = 1;k <= tot;k++)
            if((state[k]&mp[i - 1]) == 0)
            for(int p = 1;p <= tot;p++)
            if((state[p]&mp[i - 2]) == 0)
            if((state[p]&state[k]) == 0 && (state[k]&state[j]) == 0 && (state[p]&state[j]) == 0)
            dp[i % 3][k][j] = max(dp[i % 3][k][j],dp[(i - 1) % 3][p][k] + val[j]);
        }
        int ans = -1;
        for(int i = 1;i <= tot;i++)
        for(int j = 1;j <= tot;j++)
        ans = max(dp[n % 3][j][i],ans);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    康拓展开
    P6032 选择客栈 加强版 递推
    0923考试T3 二进制,位运算
    0922考试T3 dfs序 lca 线段树 树上问题
    0921考试T2
    0922考试T1
    P3934 [Ynoi2016]炸脖龙I 树状数组 扩展欧拉定理
    0922考试T4 区间DP
    P6834 [Cnoi2020]梦原 树状数组 期望DP
    UVA1364 Knights of the Round Table Tarjan求点双联通分量+二分图染色
  • 原文地址:https://www.cnblogs.com/xyj1/p/11066306.html
Copyright © 2011-2022 走看看