SGU 132 状态压缩
2013-05-22 12:42
169 查看
这道题重点在于不能有连续两个相邻的空格,不光是横向的连续两个空格的空格,还有纵向的连续两个空格也不行(把握这个这题就OK了)。之前做了一些铺瓷砖的压缩DP题,都没有在纵向有神马限制。这也是这道题的难点所在。
刚开始想的状态转移方程错了(想了好半天才发现是错的。。。T..T),原因是不能解决我说的内个重点问题,于是把内个加入到DP的状态当中。
DP
[S][Q]表示第N行状态为S,Q表示第n行和第n-1行均为空的格子的状态,这些Q状态所表示的格子要在下一行放砖时填补。
还是老套路,先对每一行搜索,搜索怎么放瓷砖,这样得到两个状态s(本行新的状态),p(上一行的状态),于是,dp
[s][q]=min{dp[n-1][p'][q']+k},其中p'与p不能有重合,q'必须满足q'&p=q',再根据这些状态算出q。
最后结果是min{dp[n-1][s][0]},s要满足保证没有相邻空格,
要用滚动数组,要在每次大循环后对一组状态清零。
附代码:
刚开始想的状态转移方程错了(想了好半天才发现是错的。。。T..T),原因是不能解决我说的内个重点问题,于是把内个加入到DP的状态当中。
DP
[S][Q]表示第N行状态为S,Q表示第n行和第n-1行均为空的格子的状态,这些Q状态所表示的格子要在下一行放砖时填补。
还是老套路,先对每一行搜索,搜索怎么放瓷砖,这样得到两个状态s(本行新的状态),p(上一行的状态),于是,dp
[s][q]=min{dp[n-1][p'][q']+k},其中p'与p不能有重合,q'必须满足q'&p=q',再根据这些状态算出q。
最后结果是min{dp[n-1][s][0]},s要满足保证没有相邻空格,
要用滚动数组,要在每次大循环后对一组状态清零。
附代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #define M 130 #define N 72 #define u (1<<m) #define cl(a) memset(a,-1,sizeof(a)) #define INF 500 using namespace std; int dp[3][M][M],a ,b[10],m,n,res; int check(int t) { int i; for (i=1;i<m;i++) if (!(t&b[i-1])&&!(t&b[i])) return 0; return 1; } void trans(int l,int s,int p1,int p,int k) { int i,q,t; t=p1+a[l-1]+p; int e=l%2; for (i=0;i<=p;i++) if ((i&p)==i) { q=u-1-(t|(s+a[l])); if (dp[1-e][p1][i]<0) continue; if (dp[e][s][q]<0) dp[e][s][q]=dp[1-e][p1][i]+k; else dp[e][s][q]=min(dp[e][s][q],dp[1-e][p1][i]+k); if (l==n&&check(s+a[l])&&!q) res=min(res,dp[e][s][q]); } } void Rundp(int l,int i,int k,int s,int p) { int p1; if (i>=m) { for (p1=0;p1<u;p1++) if (!(p1&p)&&!(p1&a[l-1])) { if (check(p1+p+a[l-1])) trans(l,s,p1,p,k); } return; } if (a[l]&b[i]) Rundp(l,i+1,k,s,p); else { Rundp(l,i+1,k,s,p); if (!(a[l-1]&b[i])) Rundp(l,i+1,k+1,s+b[i],p+b[i]); if (i<m-1&&!(a[l]&b[i+1])) Rundp(l,i+2,k+1,s+b[i]*3,p); } } void clear(int l) { int i,j; for (i=0;i<u;i++) for (j=0;j<u;j++) dp[1-l%2][i][j]=-1; } int main() { int i,j; string ss; cin>>n>>m; cl(dp); for (i=0;i<m;i++) b[i]=(1<<i); for (i=1;i<=n;i++) { cin>>ss; for (j=0;j<m;j++) { if (ss[j]=='*') a[i]+=(1<<j); } } res=INF; a[0]=u-1; dp[0][0][0]=0; for (i=1;i<=n;i++) { Rundp(i,0,0,0,0); clear(i); } cout<<res<<endl; //system("pause"); return 0; }
相关文章推荐
- SGU 132 一道很恶心的状态压缩dp
- SGU132 状态压缩~最优值
- SGU - 132 Another Chocolate Maniac (状态压缩)
- SGU 132 Another Chocolate Maniac 状态压缩DP
- SGU132 - Another Chocolate Maniac(状态压缩DP)
- sgu 223 状态压缩+方案数
- SGU 131 贴地砖类型 状态压缩DP
- SGU 396 Dance it up! 状态压缩dp
- Hardwood floor - SGU 131(状态压缩)
- Little Kings - SGU 223(状态压缩)
- SGU 536 Berland Chess 状态压缩 + BFS
- SGU 131 贴地砖类型 状态压缩DP
- SGU 131 Hardwood floor(状态压缩dp)
- SGU536 Berland Chess bfs+状态压缩
- sgu 222 - Little Rooks 简单的状态压缩DP
- sgu 223 Little Kings 状态压缩dp
- SGU223 -状态压缩DP
- SGU 197 状态压缩DP+矩阵乘法
- SGU131 状态压缩~覆盖方案数
- SGU131 - Hardwood floor(状态压缩DP)