• 洛谷2704 [NOI2001]炮兵阵地


    题目戳这里
    Solution

    状压DP很好的入门题,用熟练位运算貌似也没那么难。

    首先分析一下题目:
    看见n=100,m=10,立马就想到了状压,看起来也像DP,所以我们还是采用行号为阶段的状压DP。
    因为每个炮兵可以攻击到上面两行的范围,所以枚举i行状态时需要知道i-1和i-2行的状态。我们把每一行的状态看成一个M位的二进制数,第p位为1代表该行第p列放置了一个炮兵,0代表没有。
    在DP前,我们先预处理出集合S,代表“相邻两个1的距离不小于3”的所有M位二进制数,g数组储存对应S集合中某个数含有的1的个数。然后还需要预处理出1行和2行状态。
    那么状态定义也很明显了,f[j][k][i]表示第i行状态为j,第i-1行状态为k的方案数,那么只需枚举上一行状态和上两行状态便可以转移。
    虽然M为的二进制数有(2^M)个,但是我们只枚举S集合里面的数(其他的不合法),所以时间复杂度为(O(N|S|^2)),事实上S集合非常小。

    Coding

    #include<bits/stdc++.h>
    using namespace std;
    const int N	 = 105;
    int num,S[N*20],ans,n,m,f[N*20][N*20][101],sum[N*20],a[N],g[N];
    int count(int x)
    {
        int num=0;
        while(x) 
        {
            if(x%2==1) num++;
            x/=2;
        }
        return num;
    }
    int main()
    {
        char x;
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            for(int j=0;j<m;j++)
            { cin>>x; if(x=='H') a[i]+=1<<j;}
        for(int i=0;i<(1<<m);i++)//预处理S集合
            if(((i&(i<<1))==0)&&((i&(i<<2))==0)&&((i&(i>>1))==0)&&((i&(i>>2))==0))
            {
                S[++num]=i;
                g[num]=count(i);
                if((i&a[1])==0) f[0][num][1]=g[num];
            }
        for(int i=1;i<=num;i++)//预处理前两行
            for(int j=1;j<=num;j++)
            if(((S[i]&S[j])==0)&&((S[j]&a[2])==0))  f[i][j][2]=max(f[i][j][2],f[0][i][1]+g[j]);
        for(int i=3;i<=n;i++)
            for(int j=1;j<=num;j++)
            if((a[i]&S[j])==0)
                for(int k=1;k<=num;k++)
                    if((S[k]&S[j])==0)
                        for(int last=1;last<=num;last++)
                            if(((S[last]&S[k])==0)&&((S[last]&S[j])==0)) f[k][j][i]=max(f[k][j][i],f[last][k][i-1]+g[j]);
        for(int i=1;i<=num;i++)
            for(int j=1;j<=num;j++)
            ans=max(ans,f[i][j][n]);
        cout<<ans;
        return 0;
    }
    
  • 相关阅读:
    Spring IOC三种注入方式(接口注入、setter注入、构造器注入)(摘抄)
    java设计模式之代理模式
    JAVA学习中好网站
    程序员学习能力提升三要素
    ognl中的#、%和$
    二级缓存
    hibernate主键自动生成
    专科考研学校要求一览表
    Chapter 3: Connector(连接器)
    Chapter 2: A Simple Servlet Container
  • 原文地址:https://www.cnblogs.com/Le-mon/p/9625529.html
Copyright © 2020-2023  润新知