poj1185炮兵阵地
炮兵阵地
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 43084 | Accepted: 16457 |
Description
司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队。一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示:
如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。图上其它白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响。
现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队。
如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。图上其它白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响。
现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队。
Input
第一行包含两个由空格分割开的正整数,分别表示N和M;
接下来的N行,每一行含有连续的M个字符('P'或者'H'),中间没有空格。按顺序表示地图中每一行的数据。N <= 100;M <= 10。
接下来的N行,每一行含有连续的M个字符('P'或者'H'),中间没有空格。按顺序表示地图中每一行的数据。N <= 100;M <= 10。
Output
仅一行,包含一个整数K,表示最多能摆放的炮兵部队的数量。
Sample Input
5 4 PHPP PPHH PPPP PHPP PHHP
Sample Output
6
Source
也是状压dp入门题,代码没有,我重构了三遍,还是wa,心态爆炸了
无所谓了,能学到东西就好了
主要是学到了状压dp其实可以用三进制或者四,五进制,而且写起来不是特别麻烦的
然后是dfs的转移,还有一种提前打表的判断是否可行的方法,都是非常好的思路
还有这个判断相邻两格是否同时为1的方法,我觉得非常不错,而且方便好写
位运算还是要多学学啊
思路非常简单,就不说了。。
重构3遍。。写了我几乎一整天啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
————————————————————————————————更新于3天后
我tm在洛谷上发现了这题
然后重新交了一下,发现
我每一次重构都是没有必要的,因为,全是代码自身的逻辑错误和手残
我每一个思路都是对的,都能过
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
我在干什么
以下是我的两份的代码
#include <iostream> #include <stdio.h> #include <algorithm> #include <cmath> #include <math.h> #include <string.h> #define ll long long using namespace std; inline int read() { char c=getchar();int a=0,b=1; for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1; for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b; } int n,m,a[101][11],ans,much,f[101][60001],can[60001];//3µÄ10´Î·½ÊÇ59000+ bool in_s[60001]; int ask(int x,int i)//ÎÊ3½øÖÆÊýxµÄµÚiλÊÇɶ { int c[13],tot=0; while(x>=3) { c[++tot]=x%3; x/=3; } c[++tot]=x; while(tot<m) { c[++tot]=0; } return c[tot-i+1]; } void dfs(int x,int where,int now,int sat,int now_v)//µÚ¼¸ÅÅ£¬ÏÖÔÚµ½Á˵ڼ¸Î»£¬´ú±íÏÖÔÚµÄ״̬µÄÊý×ÖÊǶàÉÙ£¬ÉÏÒ»¸ö״̬£¬ÏÖÔڵļÛÖµÊǶàÉÙÁË { // cout<<x<<' '<<where<<endl; if(in_s[now])return ;//Èç¹ûÇ°Ã涼ÒѾ²»Âú×ãÁË£¬ºóÃæ¿Ï¶¨Ò²²»Âú×ã if(where==m+1) { f[x][now]=max(f[x][now],now_v); // if(x==3&&sat==46)cout<<now<<' '<<f[x][now]<<endl; if(x==n)ans=max(ans,f[x][now]); return ; } int no=ask(sat,where); if(no==2)//ÉÏÒ»ÐеÄÕâ¸öλÖÃÓÐÈË { dfs(x,where+1,now+pow(3,m-where),sat,now_v);//Ìî1 } else { if(no==1) { dfs(x,where+1,now,sat,now_v);//²»·Å // if(a[x][where]==0) // dfs(x,where+1,now+pow(3,m-where)*2,sat,now_v+1);//·ÅÒ»¸ö } else { dfs(x,where+1,now,sat,now_v);//²»·Å if(a[x][where]==0) dfs(x,where+1,now+pow(3,m-where)*2,sat,now_v+1);//·ÅÒ»¸ö } } } int main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); n=read();m=read(); much=pow(3,m); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { char c; cin>>c; if(c=='P')a[i][j]=0; else a[i][j]=1; } } for(int i=0;i<much;i++) { int cnt=3; for(int j=1;j<=m;j++) { if(ask(i,j)==2) { if(cnt<=2) { // if(i==56)cout<<cnt<<' '<<j<<endl; in_s[i]=1; break; } cnt=1; } else { cnt++; } } } // cout<<in_s[56]<<endl; for(int i=1;i<=n;i++) { for(int j=0;j<much;j++) { f[i][j]=-1000000; } } f[0][0]=0; dfs(1,1,0,0,0); for(int i=1;i<n;i++) { for(int j=0;j<much;j++) { if(f[i][j]>=0)//Èç¹ûÕâ¸ö״̬´æÔÚ { dfs(i+1,1,0,j,f[i][j]);//ÓÃdfsתÒÆ // cout<<f[i][j]<<' '<<i<<' '<<j<<endl; } } } cout<<ans<<endl; return 0; }
#include <iostream> #include <stdio.h> #include <algorithm> #include <cmath> #include <math.h> #include <map> #include <string.h> #define ll long long using namespace std; inline int read() { char c=getchar();int a=0,b=1; for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1; for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b; } int f[101][60][60],n,m,a[101][11],ins[1050],res[1050],tot; int check(int x,int state) { int cnt=0; for(int i=1;i<=m;i++) { if(((1<<(i-1))&state))cnt++; if(((1<<(m-i))&state)&&a[x][i]==1)return -1; } return cnt; } int main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); n=read(),m=read(); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { char c; cin>>c; if(c=='P')a[i][j]=0; else a[i][j]=1; } } for(int i=0;i<(1<<m);i++) { if((i&(i<<1))||(i&(i<<2)))continue; ins[++tot]=i; res[ins[tot]]=tot; // cout<<i<<' '<<check(1,i)<<endl; } // cout<<endl; int ans=0,now=0; for(int i=1;i<=n;i++) { for(int j=1;j<=tot;j++) { int cnt=check(i,ins[j]); if(cnt!=-1) { for(int k=1;k<=tot;k++)//ÉÏÒ»ÅÅ { now=0; if(check(i-1,ins[k])==-1)continue; if((ins[j]&ins[k])==0) { f[i][j][k]=cnt; for(int q=1;q<=tot;q++)//ÉÏÁ½ÅÅ { if(i!=1) { if(check(i-2,ins[q])==-1)continue; if((ins[q]&ins[j])==0) { if(now<f[i-1][k][q]) { now=f[i-1][k][q]; } // now=max(now,f[i-1][ins[k]][ins[q]]); } } } } f[i][j][k]+=now; if(i==n) { ans=max(ans,f[i][j][k]); } } } } } // cout<<check(6,4)<<endl; // cout<<f[6][4][9]<<endl; cout<<ans<<endl; return 0; }
一个是用三进制的,一个是用二进制的。。
(dfs还是慢一些,没办法,没开O2)
都给我调对了。。。