题目意思很明确,12这个数字很有状态压缩的意味
这一题的阶段就是按照left -> right 的顺序DP
这里一共有2^12个状态,从1 到 2^12 的数字,每个数字的二进制表示这一行的状态
状态:dp[i]表示该状态的游戏最终结果
状态转移:dp[i] = min(dp[j]), j就是从i的状态经过游戏规则所能转换的状态
ans = dp[n]
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXBIT 12
#define INF 0x3f3f3f3f
#define MAXN 1<<(MAXBIT+1)
int dp[MAXN];
int dfs(const int &idx)
{
if( -1 != dp[idx] ) {
return dp[idx];
}
int val(idx), rst(INF), flag(0), cnt(0), tmp;
for(int i = 0; i < MAXBIT; i ++) {
cnt += ((1<<i)&val)? 1 : 0;
if( (1<<i)&val && i+1 < MAXBIT && (1<<(i+1))&val ) {
if( i > 0 && !((1<<(i-1))&val) ) { //move to left
tmp = val; tmp ^= (1<<(i-1));
tmp ^= (1<<(i+1)); tmp ^= (1<<i); flag = 1;
rst = min(rst, dp[tmp] = (-1 == dp[tmp])? dfs(tmp) : dp[tmp]);
}
if( i+2 < MAXBIT && !((1<<(i+2))&val) ) { //move to right
tmp = val; tmp ^= (1<<(i+2));
tmp ^= (1<<(i+1)); tmp ^= (1<<i); flag = 1;
rst = min(rst, dp[tmp] = (-1 == dp[tmp])? dfs(tmp) : dp[tmp]);
}
}
}
if( !flag ) {
return dp[idx] = cnt;
}
return dp[idx] = rst;
}
int conversion(const char *str)
{
int rst(0);
for(int i = strlen(str)-1; i >= 0; i --) {
if( 'o' == str[i] ) {
rst += (1<<(strlen(str)-i-1));
}
}
return rst;
}
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int n;
char str[MAXBIT+1];
memset(dp, -1, sizeof(dp));
for(int i = 1<<MAXBIT; i >= 0; i --) {
dp[i] = (-1 == dp[i])? dfs(i) : dp[i];
}
while( ~scanf("%d", &n) ) {
for(int i = 0; i < n; i ++) {
scanf("%s", str);
printf("%d\n", dp[ conversion(str) ]);
}
}
return 0;
}