您的位置:首页 > 其它

uva 10651 状态压缩DP

2015-04-06 14:02 357 查看
题意:

给一串珠子-0-0-0-----00-----这样表示。

然后可以这样跳:



解析:

因为题目数量级较小,可以用dp的状态压缩通过位运算来做。

一般涉及到的位运算是 ^ 和 &。

因为^的性质是 同0不同1,比较方便。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>

#define LL long long

using namespace std;
const int maxn = 1e4;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const double pi = 4 * atan(1.0);
const double ee = exp(1.0);

int vis[maxn];
int dis[maxn];

int dp(int x)
{
if (vis[x])
return dis[x];
bool flag = true;
dis[x] = 15;
for (int i = 0; i < 12; i++)
{
if (x & (1 << i) && x & (1 << (i + 1)))
{
if (0 < i && !(x & (1 << (i - 1))))
{
int t = dp(x ^ (1 << (i + 1)) ^ (1 << i) ^ (1 << (i - 1)));
if (t < dis[x])
dis[x] = t;
flag = false;
}
if (i + 2 < 12 && !(x & (1 << (i + 2))))
{
int t = dp(x ^ (1 << (i + 2)) ^ (1 << (i + 1)) ^ (1 << i));
if (t < dis[x])
dis[x] = t;
flag = false;
}
}
}
if (flag)
{
int tmp = 0;
for (int i = 0; i < 12; i++)
{
if (x & (1 << i))
tmp++;
}
vis[x] = true;
dis[x] = tmp;
return tmp;
}
vis[x] = true;
return dis[x];
}

int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif // LOCAL
int n;
scanf("%d", &n);
getchar();
while (n--)
{
char s[20];
memset(vis, false, sizeof(vis));
memset(dis, 0, sizeof(dis));
scanf("%s", s);
int num = 0;
for (int i = 0; i < 12; i++)
{
if (s[i] == 'o')
num ^= (1 << i);
}
printf("%d\n", dp(num));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: