[NOI2001][POJ1185]炮兵阵地(状压dp)
2016-10-31 23:34
519 查看
题目描述
传送门题解
m很小并且山地和平原、放置与不放置可以用01表示,所以一看就是状压dp。但是炮可以打到上下两个格子这一点很烦人,这样的话不能用前一行向当前行转移,因为有可能在前一行的前一行存在一个炮和当前行的冲突。
那么我们在状态表示里至少要存两行的状态。但是210∗2不是有点太大了么?有趣的是,每一行的炮与炮之间至少要留两个空格,所以每一行实际的方案数要比210要小很多,即使是最大的m=10也不过只有169个,这些合法的状态是可以预处理出来的。
设f(i,j,k)表示前i行,其中最后两行为第j个和第k个状态的最大数量。然后就可以分别判断是否合法然后转移了。
理论时间复杂度是O(n(2m)3)。但是由于我们已经预处理了最多169个合法方案,中间各种判断又会砍掉很多冗余的状态,极限数据也是完全可以在2s内出解的。
代码
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define N 105 int n,m,tot,ans; int a ,sol[N*2],num[N*2],f [N*2][N*2]; char s ; int calc(int x) { int ans=0; while (x) { if (x&1) ans++; x>>=1; } return ans; } int main() { scanf("%d%d\n",&n,&m); for (int i=1;i<=n;++i) { gets(s); for (int j=1;j<=m;++j) if (s[j-1]=='P') a[i]+=(1<<(m-j)); } for (int i=0;i<=(1<<m)-1;++i) if (!(i&(i<<2))&&!(i&(i<<1))) { sol[++sol[0]]=i; num[sol[0]]=calc(i); } if (n==1) { for (int i=1;i<=sol[0];++i) if ((sol[i]&a[1])==sol[i]) ans=max(ans,num[i]); printf("%d\n",ans); return 0; } for (int i=1;i<=sol[0];++i) if ((sol[i]&a[1])==sol[i]) for (int j=1;j<=sol[0];++j) if ((sol[j]&a[2])==sol[j]) if (calc(sol[i]^sol[j])==num[i]+num[j]) f[2][i][j]=max(f[2][i][j],num[i]+num[j]); for (int i=3;i<=n;++i) for (int j=1;j<=sol[0];++j) if ((sol[j]&a[i])==sol[j]) for (int k=1;k<=sol[0];++k) if ((sol[k]&a[i-1])==sol[k]) for (int l=1;l<=sol[0];++l) if ((sol[l]&a[i-2])==sol[l]) if (calc(sol[j]^sol[k])==num[j]+num[k]&&calc(sol[k]^sol[l])==num[k]+num[l]&&calc(sol[j]^sol[l])==num[j]+num[l]) f[i][k][j]=max(f[i][k][j],f[i-1][l][k]+num[j]); for (int i=1;i<=sol[0];++i) if ((sol[i]&a )==sol[i]) for (int j=1;j<=sol[0];++j) if ((sol[j]&a[n-1])==sol[j]) if (calc(sol[i]^sol[j])==num[i]+num[j]) ans=max(ans,f [j][i]); printf("%d\n",ans); }
总结
①状压dp不要光考虑理论复杂度。合法状态有可能不是很多。②状压dp某一个不要光考虑用一维表示某一个状态,其实也可以在预处理之后表示成第几个状态。
相关文章推荐
- (状压dp)NOI 2001(POJ 1185) 炮兵阵地
- NOI 2001 & poj 1185 && NYOJ 85 炮兵阵地(状压dp)
- POJ 1185 NOI 2001 炮兵阵地 状压DP
- [POJ 1185][codevs 1647][NOI 2001]炮兵阵地 状压DP
- POJ 1185 炮兵阵地 (状压DP)
- poj 1185 炮兵阵地(状压dp)
- poj 1185 炮兵阵地(状压DP)
- poj-1185 炮兵阵地(状压dp)
- POJ 1185-炮兵阵地(状压DP)
- POJ 1185 炮兵阵地(状压dp)
- POJ1185:炮兵阵地(状压dp)
- POJ 1185 炮兵阵地(状压DP)
- poj 1185 炮兵阵地(状压dp)
- POJ 1185 [NOI2001 D2T?] 炮兵阵地
- POJ 1185 炮兵阵地 状压dp
- POJ 1185 炮兵阵地 (状压DP)
- POJ 1185 炮兵阵地 (状压dp)
- POJ 题目1185 炮兵阵地(状压DP)
- POJ 1185--炮兵阵地(状压dp)
- [POJ 1185]炮兵阵地(状压DP)