UVa 10651 - Pebble Solitaire 状态压缩 dp

Problem A
Pebble Solitaire
Input:
 standard input
Output: standard output
Time Limit: 1 second
 

Pebble solitaire is an interesting game. This is a game where you are given a board with an arrangement of small cavities, initially all but one occupied by a pebble each. The aim of the game is to remove as many pebbles as possible from the board. Pebbles disappear from the board as a result of a move. A move is possible if there is a straight line of three adjacent cavities, let us call them AB, and C, with B in the middle, where A is vacant, but B and C each contain a pebble. The move constitutes of moving the pebble from C to A, and removing the pebble in Bfrom the board. You may continue to make moves until no more moves are possible.

 

In this problem, we look at a simple variant of this game, namely a board with twelve cavities located along a line. In the beginning of each game, some of the cavities are occupied by pebbles. Your mission is to find a sequence of moves such that as few pebbles as possible are left on the board.

 

Input

The input begins with a positive integer n on a line of its own. Thereafter n different games follow. Each game consists of one line of input with exactly twelve characters, describing the twelve cavities of the board in order. Each character is either '-' or 'o' (The fifteenth character of English alphabet in lowercase). A '-' (minus) character denotes an empty cavity, whereas a 'o' character denotes a cavity with a pebble in it. As you will find in the sample that there may be inputs where no moves is possible.

 

Output

For each of the n games in the input, output the minimum number of pebbles left on the board possible to obtain as a result of moves, on a row of its own.

 

Sample Input                              Output for Sample Input

5

---oo-------

-o--o-oo----

-o----ooo---

oooooooooooo

oooooooooo-o

1

2

3

12

1

 



----------------------------------------------------------

啊,难得把状态压对一次。

令黑色为1,白色为0。

f[x]表示状态x所能完成的最大转换数。f[x]=max( f[t]+1 ) (x可以到达t)

黑色个数-f[x]即为答案。

-----------------------------------------------------------

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

//110=6 001=1 011=3 100=4

int f[1<<12];
int tmp;

int dfs(int x)
{
    //cerr<<"x= "<<x<<endl;
    //getchar();
    if (f[x]!=-1) return f[x];
    int ret=0;
    for (int i=0;i<10;i++)
    {
        int t=x;
        if ( (x&(1<<(i+2))) && (x&(1<<(i+1))) && (x&(1<<i))==0 )
        {
            t^=(6<<i);
            t|=(1<<i);
            //cerr<<"check ok x= "<<x<<" i= "<<i<<" 6<<i= "<<(6<<i)<<" t="<<t<<endl;
            ret=max( ret, dfs(t)+1 );
        }
        t=x;
        if ( (x&(1<<(i+2)))==0 && (x&(1<<(i+1))) && (x&(1<<i)) )
        {
            t^=(3<<i);
            t|=(4<<i);
            //cerr<<"check ok x= "<<x<<" t="<<t<<endl;
            ret=max( ret, dfs(t)+1 );
        }
    }
    f[x]=ret;
    return ret;
}

int main()
{
    int T;
    char s[20];
    int black,bit;
    memset(f,-1,sizeof(f));
    scanf("%d",&T);
    while (T--)
    {
        bit=0;
        black=0;
        scanf("%s",s);
        for (int i=0;s[i];i++)
        {
            if (s[i]=='o')
            {
                bit|=(1<<i);
                black++;
            }
        }
        //读入完毕
        int ans=dfs(bit);
        printf("%d\n",black-ans);
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值