炮兵阵地

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

题意:这道题太经典了,看到题目就知道题意,故题意略。

题解:经典的状压dp。以前觉得dp是个很难的东西,做了这一题之后发现,dp其实根本不难,真的,而且很好打。

思维过程:拿到题之后,由于之前做过,所以知道是状压dp。接着想怎么解决。普通的dp,不要考虑障碍,这一题中有障碍限制。多以第一步要处理这个障碍。想到了用这样的方式来解决。把出现h的地方标记为1,其余记0,从右到左,从低位到高位,求出这个数,然后枚举状态的时候,只要把枚举的状态,和这个数&,如果出现1则是不满足的,说明有炮兵出现在H上。好了,障碍解决了。接下来可以dp。一开始想到的是用二维的,发现打出的结果不对,检查一一下,貌似转移不太对。于是,就考虑三维的了。一下子豁然开朗,思路很清晰了。打完之后,过了样例,接着交了,结果wa。不知道错在哪里,就看了discuss。其实这是不对的,应该自己思考。其实,这时候,如果找不出来错误,应该具几组特例的。会发现 11 p,就不对,然后就知道错在哪里,一开始我是第一行初始化dp[i][0],但是最后的结果却是从1开始枚举,所以如果样例只有1,2行的话,答案就不对了。于是,改改,交了,就过了。这里还有一个问题,就是,dp[][i][j],记录的是第i个状态,不是i所代表的状态,真正的状态是s[i],这样就节省了很多空间,这样开3维的才有可能。接下来,是我的代码。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 int n,m;
 7 char mp[102][12];
 8 int state[102];
 9 int ct[1003],num,s[1003];
10 int dp[102][67][67];
11 bool isok(int x){
12   if((x&(x<<1))||(x&(x<<2)))return false;
13   return true;
14 }
15 void solve1(){
16   for(int i=1;i<=n;i++){
17         int counts=1,ans=0;
18     for(int j=m;j>=1;j--){
19         if(mp[i][j]==‘H‘)
20           ans+=counts;
21          counts*=2;
22     }
23     state[i]=ans;
24   }
25 }
26 int counts(int x){
27     int ans=0;
28     while(x){
29         ans+=(x&1);
30         x/=2;
31     }
32   return ans;
33 }
34 void solve2(){
35   num=0;
36   for(int i=0;i<(1<<m);i++){
37     if(isok(i)){
38         num++;
39         s[num]=i;
40         ct[num]=counts(i);
41     }
42   }
43 }
44 int main(){
45   while(~scanf("%d%d",&n,&m)){
46        memset(mp,0,sizeof(mp));
47        memset(dp,0,sizeof(dp));
48        memset(ct,0,sizeof(ct));
49        memset(s,0,sizeof(s));
50        memset(state,0,sizeof(state));
51        for(int i=1;i<=n;i++)
52           for(int j=1;j<=m;j++)
53            cin>>mp[i][j];
54        solve1();
55        solve2();
56        for(int i=1;i<=num;i++){
57         if(s[i]&state[1])continue;
58         dp[1][i][0]=ct[i];
59        }
60        for(int i=1;i<=num;i++){
61           for(int j=1;j<=num;j++){
62             if(s[i]&s[j])continue;
63             if(state[2]&s[i])continue;
64             if(state[1]&s[j])continue;
65             dp[2][i][j]=max(dp[2][i][j],dp[1][j][0]+ct[i]);
66           }
67        }
68        for(int i=3;i<=n;i++){
69           for(int j=1;j<=num;j++){
70              if(s[j]&state[i])continue;
71             for(int k=1;k<=num;k++){
72                  if(s[k]&s[j])continue;
73                   if(s[k]&state[i-1])continue;
74                  for(int g=1;g<=num;g++){
75                     if(s[k]&s[g])continue;
76                     if(s[j]&s[g])continue;
77                     if(s[g]&state[i-2])continue;
78                     dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][g]+ct[j]);
79                 }
80             }
81           }
82        }
83      int ans=0;
84      for(int i=1;i<=num;i++){
85         for(int j=0;j<=num;j++)
86         ans=max(ans,dp[n][i][j]);
87      }
88      printf("%d\n",ans);
89   }
90 }

炮兵阵地,布布扣,bubuko.com

时间: 2024-08-06 07:57:15

炮兵阵地的相关文章

POJ 1185 炮兵阵地 状压dp

http://poj.org/problem?id=1185 经典题目不必多说,直接贴代码. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 int n, m, cnt, size; 7 int a[110], st[70], ct[70]; 8 char str[15]; 9 int f[110][70][70]; 10 void init(

xtu DP Training C.炮兵阵地

炮兵阵地 Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: 118564-bit integer IO format: %lld      Java class name: Main 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表

状压DP 洛谷P2704 炮兵阵地

P2704 炮兵阵地 题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图.在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队):一支炮兵部队在地图上的攻击范围如图中黑色区域所示: 如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格.图上其它白色网格

状态压缩动态规划 -- 炮兵阵地

司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队,一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图.在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队):一支炮兵部队在地图上的攻击范围如图中黑色区域所示: 如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格.图上其它白色网格均攻击不到.从图上可见炮兵的攻击

Poj 1185 炮兵阵地(状态压缩dp 入门题)

炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17272   Accepted: 6593 Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图.在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队):一支炮兵部队在地图上的攻击

poj 1185 炮兵阵地 (状态压缩DP)

炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 19690   Accepted: 7602 Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图.在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队):一支炮兵部队在地图上的攻击

POJ1185 炮兵阵地 状态压缩DP

B - 炮兵阵地 Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-06-29) Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用&quo

HDU1185:炮兵阵地(状态压缩)

Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图.在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队):一支炮兵部队在地图上的攻击范围如图中黑色区域所示: 如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格.图上其它白色网格均攻击不

【NOI2001】炮兵阵地

[题目描述] 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图.在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队):一支炮兵部队在地图上的攻击 范围如图中黑色区域所示: 如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格.图上其它白色网格均攻击不到.从图