经典题了
枚举初始状态的磁头位置,求出哪些位置可以随意改动,然后大力容斥
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=1010;
int n,tot,cg[40];
ll p[40],ans;
inline int count(ll S){
int ret=0;
for(int i=0;i<n;i++) if(S>>i&1) ret++;
return ret;
}
void dfs(int x,ll S,int t){
if(x>tot){
if(t){
if(t&1) ans+=1LL<<count(S);
else ans-=1LL<<count(S);
}
return ;
}
if(!S) return ;
dfs(x+1,S,t);
dfs(x+1,S&p[x],t+1);
}
class MapGuessing{
public:
ll countPatterns(string goal, vector<string> C){
string code;
for(int i=0;i<C.size();i++) code+=C[i];
n=goal.size(); int m=code.size();
for(int i=0;i<n;i++){
int cur=i,f=0; ++tot; p[tot]=0;
for(int j=0;j<n;j++) cg[j]=0;
for(int j=0;j<m;j++){
if(code[j]=='>') cur++;
if(code[j]=='<') cur--;
if(code[j]=='0') cg[cur]=1;
if(code[j]=='1') cg[cur]=2;
if(cur<0 || cur>=n){
tot--; break;
}
int flg=1;
for(int k=0;k<n;k++)
if(cg[k] && '0'+cg[k]-1!=goal[k]){
flg=0; break;
}
if(flg){
for(int k=0;k<n;k++)
if(cg[k]) p[tot]|=1LL<<k;
}
}
}
dfs(1,(1LL<<n)-1,0);
return ans;
}
}Main;
int main(){
string a= "11100011010111111010100100110001101";
vector<string> b= {"11111111111111111111",
"1<><><><><><><><><>1",
"1<>000>000><0<><0<>1",
"1<0<><>0><0<00>00<>1",
"1<>00<>000><0<0<0<>1",
"1<><>0>0><0<0<><0<>1",
"1<000<>0><0<0<><0<>1",
"1<><><><><><><><><>1",
"1<>000><000<>000><>1",
"1<>0><><0<><>0><><>1",
"1<>000><000<>000><>1",
"1<><>0><><0<><>0><>1",
"1<>000><000<>000><>1",
"1<><><><><><><><><>1",
"11111111111111111111"};
cout<<Main.countPatterns(a,b);
for(;;);
}