首页 > 其他分享 >P2704 [NOI2001] 炮兵阵地

P2704 [NOI2001] 炮兵阵地

时间:2024-07-21 21:29:28浏览次数:11  
标签:cnt return sit int 炮兵阵地 long NOI2001 P2704

原题链接

题解

经典的状压dp

code

#include<bits/stdc++.h>
#define ll long long
#define lowbit(x)  ((x)&(-x))
using namespace std;

int sit[105];
int dp[505][505][4];

bool check(int x)
{
    int x1=(x>>1)>>1;
    int x2=(x<<1)<<1;
    int x3=(x<<1);
    int x4=(x>>1);
    if((x1&x)||(x2&x)||(x3&x)||(x4&x)) return 0;
    else return 1;
}

int cal(int x)
{
    int cnt=0;
    while(x)
    {
        x-=lowbit(x);
        cnt++;
    }
    return cnt;
}

void solve()
{
    int n,m;
    cin>>n>>m;

    for(int i=1;i<=n;i++)
    {
        string s;
        cin>>s;

        for(int j=0;s[j];j++)
        {
            sit[i]<<=1;
            sit[i]|=(s[j]=='H'?1:0);
        }
    }

    vector<int> line,sum;
    for(int i=0;i<=(1<<m)-1;i++)
    {
        if(check(i))
        {
            line.push_back(i);
            sum.push_back(cal(i));
        }
    }

    int ans=0;
    for(int i=0;i<line.size();i++)
    {
        if((sit[1]&line[i])==0)
        {
            dp[i][0][1]=sum[i];
            ans=max(ans,dp[i][0][1]);
            //printf("1 : down:%d  mid:0  up:0  num:%d\n",line[i],sum[i]);
        }
    }

    if(n==1)
    {
        cout<<ans;
        return;
    }
    for(int i=0;i<line.size();i++)
    {
        for(int j=0;j<line.size();j++)
        {
            if((sit[2]&line[j])==0&&(line[j]&line[i])==0&&(line[i]&sit[1])==0)
            {
                dp[j][i][2]=dp[i][0][1]+sum[j];
                ans=max(ans,dp[j][i][2]);
                //printf("2 : down:%d  mid:%d  up:0  num:%d\n",line[j],line[i],sum[i]+sum[j]);
            }
        }
    }


    if(n==2)
    {
        cout<<ans;
        return;
    }

    for(int i=3;i<=n;i++)
    {
        for(int j=0;j<line.size();j++)
        {
            if(line[j]&sit[i]) continue;
            for(int k=0;k<line.size();k++)
            {
                if(line[k]&sit[i-1]) continue;
                if(line[k]&line[j]) continue;
                for(int l=0;l<line.size();l++)
                {
                    if(line[l]&sit[i-2]) continue;
                    if(line[l]&line[k]) continue;
                    if(line[l]&line[j]) continue;

                    dp[j][k][i%3]=max(dp[j][k][i%3],dp[k][l][(i-1)%3]+sum[j]);
                    ans=max(ans,dp[j][k][i%3]);
                   // printf("%d : down:%d  mid:%d  up:0  num:%d\n",i,line[i],line[j],line[k],dp[j][k][i%3]);
                }
            }
        }
    }

    cout<<ans;
}
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t=1;
    //cin>>t;
    while(t--) solve();
    return 0;
}


标签:cnt,return,sit,int,炮兵阵地,long,NOI2001,P2704
From: https://www.cnblogs.com/pure4knowledge/p/18314974

相关文章

  • P2024 [NOI2001] 食物链
    原题链接题解带权并查集的应用,普通的并查集只能表示结点间的一种关系(如同一集合中的都是朋友)。而带权并查集的结点权值表示该结点与根结点的关系。相对应,带权并查集的路径压缩也复杂了一点。code #include<bits/stdc++.h>usingnamespacestd;constintN=5e4+5;intn,k......
  • P2024 [NOI2001] 食物链
    Solution:使用拓展域并查集,\(1-n\)表示\(\rmA\)群落,\(n+1-2n\)是\(\rmB\)群落,\(2n+1-3n\)是\(\rmC\)群落那么对于操作一,我们首先判断\(x\)是否吃了\(y\)或\(y\)是否吃了\(x\).若吃了,那么这句话为假若没吃,则将(x,y)(x+n,y+n)(x+2n,y+2n)三条边连......
  • poj1185炮兵阵地
    炮兵阵地TimeLimit:2000MS MemoryLimit:65536KTotalSubmissions:43084 Accepted:16457Description司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队。一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H"表示),也可能是平原(用"P"表示),如下图。......
  • [NOI2001] 陨石的秘密
    题目描述公元11380年,一颗巨大的陨石坠落在南极。于是,灾难降临了,地球上出现了一系列反常的现象。当人们焦急万分的时候,一支中国科学家组成的南极考察队赶到了出事地点。经过一番侦察,科学家们发现陨石上刻有若干行密文,每一行都包含5个整数:11116006357801132845著......
  • P2024 [NOI2001] 食物链
    P2024[NOI2001]食物链法一:种类并查集A->B->C->A[1,n]:表示同类,[n+1,2n]:表示猎物,[2n+1,3*3]:表示天敌点击查看代码#include<bits/stdc++.h>usingnamespacestd;constintN=5e4+10;intfa[3*N];intfind(intx){ returnx==fa[x]?x:fa[x]=find(fa[x......
  • Ynoi2001 冷たい部屋、一人 题解
    \(\text{link}\),这题太毒瘤啦!难写难调还略微卡常。谁爱卡常谁卡吧。反正我先贺为敬了。——引用自洛谷别人的提交记录本人写了两天(两个\(case\)各一天),调崩溃了才调出来,太毒瘤了!看到颜色相同发现不弱于\(O(n\sqrtn)\),一眼根号分治,设阈值为\(B\)。case1对于颜色出现次......
  • P2024 [NOI2001] 食物链 || #576. 食物链【NOI2001】 (并查集)
    空降锣鼓空降OJ题解:#include<bits/stdc++.h>usingnamespacestd;intn,k;intd,x,y;intans;intfa[500050];intfind(intx){//找爸爸 if(fa[x]==x) returnfa[x]; returnfind(fa[x]);}intmain(){ cin>>n>>k; for(inti=1;i<=n*3;i++)//开三个并查集风......
  • POJ 1185 炮兵阵地
    感觉上很难,确实自己做一开始没有想到是dp问题,同时没有进行剪枝,同时有一些准备工作没有做好没有提前将每一行的信息转成数字信息(做题经验不足)没有提前把每行可能的情况抽......
  • P1024 [NOI2001] 食物链【种类并查集】
    题意P1024简化题意:给定\(n\)和\(k(n\leqslant5\times10^4,k\leqslant10^5)\),表示有\(n\)个动物,\(k\)个描述,其中:\(n\)个动物分别属于\(A,B,C\)中的一种,定义......
  • 洛谷P2024 [NOI2001] 食物链
    slojP2577.食物链题目大意说实话,我做对了之后都还是有点懵语文不好都这么招歧视了吗,我太难了三类动物A,B,C,A吃B,B吃C,C吃A。给出若干关系,判断第几个关系是错误的......