P2704 [NOI2001]炮兵阵地

P2704

简单说说吧 : Dp[i][I][J]表示当前为第i行,状态为I, 上一行的状态为J, 所以呢有:

Dp[i][I][J] = max(Dp[i][I][J], Dp[i - 1][J][K] + Sum[I])

Sum[I]表示该状态下可以放多少炮兵, K为上上行的状态

这道题非常的简单, 简直是大水题!

 1 #include <cstdio>
 2 #include <iostream>
 3 #define lowbit(X) ((X) & -(X))
 4 
 5 using namespace std;
 6 
 7 int N, M, Ans;
 8 int Dp[2][(1 << 11)][(1 << 11)], Sum[(1 << 11)], Map[105];
 9 char O;
10 
11 inline int Get(int X)
12 {
13     int Cnt(0);
14     while (X)
15     {
16         X -= lowbit(X);
17         ++Cnt;
18     }
19     return Cnt;
20 }
21 
22 int main()
23 {
24     scanf("%d %d", &N, &M);
25     for (int i = 0; i < N; ++i)
26         for (int j = 0; j < M; ++j)
27         {
28             cin >> O;
29             Map[i] <<= 1, Map[i] |= (O == 'H');
30         }
31     for (int i = 0; i < (1 << M); ++i) Sum[i] = Get(i);
32     for (int i = 0; i < (1 << M); ++i)
33     {
34         if ((i & Map[0]) || (i & (i << 1)) || (i & (i << 2)))continue;
35         Dp[0][i][0] = Sum[i];
36     }
37     for (int I = 0; I < (1 << M); ++I)
38         for (int J = 0; J < (1 << M); ++J)
39         {
40             if (!Dp[0][J][0] || I & Map[1] || I & (I << 1) || I & (I << 2) || I & J)continue;
41             Dp[1][I][J] = Sum[I] + Sum[J];
42         }
43     for (int i = 2; i < N; ++i)
44         for (int I = 0; I < (1 << M); ++I)
45         {
46             if (I & Map[i] || I & (I << 1) || I & (I << 2))continue;
47             for (int J = 0; J < (1 << M); ++J)
48             {
49                 if (J & Map[i - 1] || J & (J << 1) || J & (J << 2) || I & J)continue;
50                 Dp[i & 1][I][J] = 0;
51                 for (int K = 0; K < (1 << M); ++K)
52                 {
53                     if (K & Map[i - 2] || K & (K << 1) || K & (K << 2) || I & K || J & K)continue;
54                     Dp[i & 1][I][J] = max(Dp[i & 1][I][J], Dp[!(i & 1)][J][K] + Sum[I]);
55                 }
56             }
57         }
58     for (int i = 0; i < (1 << M); ++i)
59         for (int j = 0; j < (1 << M); ++j)
60             Ans = max(Ans, Dp[(N - 1) & 1][i][j]);
61     printf("%d\n", Ans);
62 }
View Code
posted @ 2019-12-31 19:08  BlogOfASBOIER  阅读(142)  评论(0)    收藏  举报