bzoj1088 P2327 [SCOI2005]扫雷
emmmmm.....这题真可以用状压写
因为每个数字只对3个格子有影响,相当于只有2^3=8种状态,所以可以用状压瞎搞
我们用8个数字代表二进制下的8种状态
0 000 ; 1 001 ; 2 010 ; 3 011 ;
4 100 ; 5 101 ; 6 110 ; 7 111 ;
0/1表示无/有雷
设 f[ i ][ j ]表示在第 i-2 ~ i 个格子的状态为 j 的方案数
状态转移时(设当前状态为 i)相当于 f[ i+1 ][ j ]=f[ i ][ j>>1 ]+f[ i ][ j>>1|1 ]
但是我懒得写判断所以直接手算可行转移了(逃
注意不能省略 三个格都为0的情况
#include<cstdio> using namespace std; int n,f[10002][8]; int main(){ scanf("%d",&n); int opt; scanf("%d",&opt); if(opt==1) f[2][1]=f[2][2]=1; else if(opt==2) f[2][3]=1; else if(opt==0) f[2][0]=1; for(int i=2;i<=n;++i){//把数字转二进制自己观察吧qwq scanf("%d",&opt); if(opt==1){ f[i+1][1]=f[i][4]+f[i][0]; f[i+1][2]=f[i][1]+f[i][5]; f[i+1][4]=f[i][2]+f[i][6]; }else if(opt==2){ f[i+1][3]=f[i][1]+f[i][5]; f[i+1][5]=f[i][2]+f[i][6]; f[i+1][6]=f[i][3]+f[i][7]; }else if(opt==3) f[i+1][7]=f[i][3]+f[i][7]; else f[i+1][0]=f[i][0]+f[i][4]; } printf("%d",f[n+1][0]+f[n+1][2]+f[n+1][4]+f[n+1][6]); //注意第 n+1 个格子必须为0 return 0; }