状态压缩基础题2道
来源:互联网 发布:手机双桌面软件 编辑:程序博客网 时间:2024/06/08 10:14
最近队友们都在专注状态压缩,于是果断凑凑热闹。。。。昨天看了他们正在看的一份资料,写的非常不错,话说国家集训队论文对我这个小菜鸟而言高深莫测,各种看不懂,这份资料可以说写的相当不错,由浅入深,最重要的是细节部分写的很到位(PS:其实看集训队论文还是经典的,但需要读者有较好的基本功的)
对状态压缩已有了最基本的了解,尤其是预处理意识对初学者来讲很重要的,它可以减少代码复杂度和时间复杂度。此外,位运算代码书写要格外注意哟,好,开始上题。
POJ 1185 炮兵阵地
这是经典的老NOI试题,状态压缩入门必刷题。首先是预处理每一行中哪些状态时可行的,用dfs实现。状态转移方程F[i][S1][S2] = max{F[i-1][s2][s3]},s1,s2,s3为第i行,i-1行,i-2行状态。并且三个状态之间不冲突。由于需要空间过多,需要滚动数组,附代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <vector>#define N 104#define M 1027#define pb push_back#define ss(a) scanf("%d",&a)#define cl(a) memset(a,0,sizeof(a))using namespace std;int a[N],m,n,res;vector<int> s[N];int f[2][M][M],bit[M];void clearing(){ cl(f);cl(a); for (int i=1;i<=n;i++) s[i].clear();}void init(int i,int x,int d,int value){ int j; if (i<0) { s[0].pb(value); bit[value]=d; for (j=1;j<=n;j++) if ((value&a[j])==value) s[j].pb(value); } else { init(i-1,x,d,value); if (x<0||x-i>2) { int t=1<<i; init(i-1,i,d+1,value+t); } }}void inition(){ int i,j; for (i=0;i<(1<<m);i++) { for (j=0;j<(1<<m);j++) if ((i&a[1])==i) f[1][i][j]=bit[i]; res=max(res,f[1][i][0]); } }int main(){ int i,j,k,l,x,y,z,e; while (ss(n)!=EOF) { ss(m); clearing(); for (i=1;i<=n;i++) for (j=1;j<=m;j++) { char ch; cin>>ch; if (ch=='P') a[i]+=(1<<(m-j)); } init(m-1,-1,0,0); res=-1; inition(); for (i=2;i<=n;i++) for (j=0;j<s[i].size();j++) { x=s[i][j]; for (k=0;k<s[i-1].size();k++) { y=s[i-1][k]; e=i%2; f[e][x][y]=0; if (!(x&y)) { for (l=0;l<s[i-2].size();l++) { z=s[i-2][l]; if (i==2||!((x&z)||(y&z))) { f[e][x][y]=max(f[e][x][y],f[1-e][y][z]+bit[x]); } } } res=max(res,f[e][x][y]); } } printf("%d\n",res); } return 0;}
POJ 2411
还是一道很经典的题,方块问题。F[i][S]=sigma(f[i-1][s1]),其中s和s1无重复单元格,并填满上一行。注意S1可以使全0状态。初始值F[0][2^W-1]=1。要用到i64,附代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#define ll __int64#define N (1<<11)+10#define u (1<<w)-1#define ss(a,b) scanf("%d%d",&a,&b)#define cl(a) memset(a,0,sizeof(a))using namespace std;int a[N][N],w;ll f[13][N];int pd(int i,int j,int w){ int p,q,x=1,y=0,k; if ((i|j)!=u) return 0; for (k=0;k<w;k++) { p=i&x; q=j&x; if (p&q) y=(y+1)%2; else if (y!=0) return 0; x*=2; } if (y) return 0; else return 1;}int main(){ int i,j,k,m,n,h; while (ss(h,w)!=EOF) { if (h==0&&w==0) break; if ((h*w)%2>0) { cout<<0<<endl; continue; } cl(a); for (i=0;i<=u;i++) for (j=0;j<=u;j++) if (pd(i,j,w)) a[i][j]=1; cl(f); f[0][u]=1; for (i=1;i<=h;i++) for (j=0;j<=u;j++) for (k=0;k<=u;k++) if (f[i-1][j]>0&&a[j][k]) { f[i][k]+=f[i-1][j]; } printf("%I64d\n",f[h][u]); } return 0;}
- 状态压缩基础题2道
- 状态压缩DP基础题解题报告
- poj2817(状态压缩dp基础题)
- 【状态压缩】---状态压缩dp第一题
- DP(2) 状态压缩
- [hihocoder1048]状态压缩2
- 状态压缩2 poj3279
- POJ 3254 (基础 状态压缩 DP )
- 状态压缩(1)--hdu5094(状态压缩+bfs)(能力题)
- 状态压缩DP入门题
- 状态压缩DP入门题
- 状态压缩dp入门题
- hdu3182 状态压缩水题
- 状态压缩DP入门题
- 状态压缩棋盘问题2道 sgu131&poj1038
- 状态压缩(2)+模拟枚举(2)--poj3279(能力题)
- NOIP 2017 Day2 题2:宝藏 状态压缩
- 状态压缩
- 关于算法的介绍
- 提升自己的Opencv境界
- OpenCV 获取摄像头并显示摄像头视频
- MongoDB GridFS图片存储
- 压缩算法
- 状态压缩基础题2道
- C++中的大括号{}
- VS2010下配置 OpenCV2.2
- HDOJ1404(SG博弈)
- Opencv 图片的初步处理——平滑处理
- 题目1115:数字求和
- OpenCV调用摄像头录像并保存下来
- Hibernate关联映射及配置
- HDU2159--FATE