题目大意:
类似于跳棋,求最后剩下几个。
思路:
位运算+记忆化搜索 状态压缩
代码:
#include <iostream>
using namespace std;
#include <stdio.h>
#include <cstring>
const int MAXN = 4100;
int vis[MAXN],_min;
char s[15];
bool check(int k,int i) {
if((k & (1 << (i - 1))) && (k & (1 << i)) && !(k & (1 << (i + 1)))) //oo-这种情况
return true;
if(!(k & (1 << (i - 1))) && (k & (1 << i)) && (k &(1 << (i + 1))))//-oo这种情况
return true;
return false;
}
void dp(int k) {
if(vis[k])
return ;
for(int i = 1; i <= 10; i++) {
int t = k;
if(check(k,i)) { //满足条件就可以跳
t ^= (1 << (i - 1));
t ^= (1 << i);
t ^= (1 << (i + 1));
dp(t);
}
}
int cnt = 0;
for(int i = 0; i < 12; i++)
if(k & (1 << i))
cnt++;
_min = min(_min,cnt);
vis[k] = cnt;
}
int main() {
int n;
scanf("%d",&n);
getchar();
while(n--) {
gets(s);
int a = 0;
for(int i = 0; i < 12; i++)
if(s[i] == 'o')
a |= (1 << i);
memset(vis,0,sizeof(vis));
_min = 13;
dp(a);
printf("%d\n",_min);
}
return 0;
}