[P2704][NOI2001]炮兵阵地 (状态压缩)
最近抄状压的代码……
然后盯上了这个题目
调试了一个晚上,终于A了
但是是对着宝典打的,我依然不懂状态压缩
那么下一步先把装压放一放,学一下树形DP吧
#include<cstdio> #include<iostream> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<cstring> #include<string> using namespace std; int n,m,s[110][150]; int f[110][150][150]; int num[110][150]; bool map[1100][1100]; int getnum(int x) { int t=0; while(x>0){ x=x&(x-1); t++; } return t; } void dp(){ s[0][0]=1; int s1,s2,m=1; for(int i=1;i<=n;i++,m=m^1) for(int a=1;a<=s[i-1][0];a++){ s1=s[i-1][a]; for(int b=1;b<=s[i][0];b++) if(map[s1][s[i][b]]){ s2=s[i][b]; if(i==1) f[m][a][b]=max(f[m][a][b],num[i][b]); else{ for(int c=1;c<=s[i-2][0];c++) if(map[s[i-2][c]][s1] && map[s[i-2][c]][s2]) f[m][a][b]=max(f[m][a][b],f[m^1][c][a]+num[i][b]); } } } int ans=0; m=m^1; for(int a=1;a<=s[n-1][0];a++) for(int b=1;b<=s[n][0];b++) ans=max(ans,f[m][a][b]); cout<<ans; } int main() { int q;cin>>n>>m; string tmp; for(int i=1;i<=n;i++) { cin>>tmp; q=0; for(int j=0;j<tmp.size();j++){ if(tmp[j]=='P') q=(q<<1); else q=(q<<1)|1; } for(int j=0;j<(1<<m);j++){ if((j<<1)&j || (j<<2)&j || (j>>1)&j || (j>>2)&j) continue; if(q&j) continue; ++s[i][0]; s[i][s[i][0]]=j; num[i][s[i][0]]=getnum(j); } } for(int i=0;i<=(1<<m);i++){ for(int j=0;j<=(1<<m);j++) if(!(i&j)) map[i][j]=true; } dp(); return 0; }