zoukankan      html  css  js  c++  java
  • POJ 1185 炮兵阵地(状压dp)

    http://poj.org/problem?id=1185

    题意:

    思路:

    每一行最多只有10列,所以可以用二进制来表示每一行的状态。

    d【i】【j】【k】表示第i行状态为k时,并且上一行状态为j时的最大炮兵数。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<sstream>
      6 #include<vector>
      7 #include<stack>
      8 #include<queue>
      9 #include<cmath>
     10 #include<map>
     11 #include<set>
     12 using namespace std;
     13 typedef long long ll;
     14 typedef pair<int,int> pll;
     15 const int INF = 0x3f3f3f3f;
     16 const int maxn = 20+5;
     17 
     18 int n, m;
     19 
     20 char s[20];
     21 int st[105];
     22 int tmp[105];
     23 int num[105];
     24 int d[105][105][105];
     25 
     26 int calc(int x)
     27 {
     28     int tmp=0;
     29     while(x)
     30     {
     31         if(x&1)  tmp++;
     32         x>>=1;
     33     }
     34     return tmp;
     35 }
     36 
     37 int main()
     38 {
     39     //freopen("in.txt","r",stdin);
     40     while(~scanf("%d%d",&n, &m))
     41     {
     42         getchar();
     43         for(int i=1;i<=n;i++)
     44         {
     45             scanf("%s",&s);
     46             st[i]=0;
     47             for(int j=0;j<m;j++)
     48             {
     49                 st[i]=(st[i]<<1)|(s[j]=='P');
     50             }
     51         }
     52 
     53         int top=0;
     54         for(int i=0;i<(1<<m);i++)  //记录可行状态
     55         {
     56             if(!(i&(i<<1)) && !(i&(i<<2)))
     57             {
     58                 tmp[top]=i;
     59                 num[top]=calc(i);
     60                 top++;
     61             }
     62         }
     63 
     64         int ans=0;
     65         memset(d,-1,sizeof(d));
     66         for(int i=0;i<top;i++)  //第一行状态
     67         {
     68             if((st[1]|tmp[i])==st[1])   d[1][0][i]=num[i];
     69         }
     70 
     71         for(int i=2;i<=n;i++)
     72         {
     73             for(int j=0;j<top;j++)  //第i行状态
     74             {
     75                 if((st[i]|tmp[j])!=st[i])  continue;
     76 
     77                 for(int k=0;k<top;k++)  //第i-1行状态
     78                 {
     79                     if((st[i-1]|tmp[k])!=st[i-1])  continue;
     80                     if(tmp[j]&tmp[k])  continue;  //和第i行有冲突
     81 
     82                     for(int t=0;t<top;t++)  //第i-2行状态
     83                     {
     84                         if(i>2)
     85                         {
     86                             if((st[i-2]|tmp[t])!=st[i-2])  continue;
     87                             if(tmp[t]&tmp[k])  continue;
     88                             if(tmp[t]&tmp[j])  continue;
     89                         }
     90 
     91                         d[i][k][j]=max(d[i][k][j],d[i-1][t][k]+num[j]);
     92                     }
     93                 }
     94             }
     95         }
     96         
     97         for(int i=0;i<top;i++)
     98             for(int j=0;j<top;j++)
     99             ans=max(ans,d[n][i][j]);
    100         printf("%d
    ", ans);
    101     }
    102     return 0;
    103 }
  • 相关阅读:
    ASP.NET 备份恢复SqlServer数据库
    ASP.NET MVC3.0 Razor 视图模板 语法
    ASP.NET 缓存
    代码生成框架
    C#中HashTable的用法
    C# 概念 委托和事件
    Web Service 系列 → Web Service 简介
    CDN 内容分发网络
    HarmonyOS开发者创新大赛
    #2020征文手表#【图解鸿蒙】多组示例演示三个样式的组合用法
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7092845.html
Copyright © 2011-2022 走看看