Pebble Solitaire+uva+状态压缩+记忆化搜索

Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu

Description

Download as PDF

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 A, B, 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 B from 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

 




解决方案:求按照它的规则移动pebble,求最后剩下的最少的pebble个数。一维的,有12个位置,可用状态压缩则共1<<12个状态,然后记忆化搜索即可。

code:

#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1<<14;
const int inf=0x3f3f3f3f;
int dp[maxn];
char text[14];
int tempbit[14];
void copy(int bit[])
{
    for(int i=0; i<12; i++)
    {
        tempbit[i]=bit[i];
    }
}
int gert()
{
    int temp=0;
    for(int i=11; i>=0; i--)
    {
        temp<<=1;
        temp|=tempbit[i];
    }
    return temp;
}
int getcount(int k)
{
    int cnt=0;
    for(int i=0; i<12; i++)
    {
        cnt+=((k>>i)&1);
    }
    return cnt;
}
int dfs(int k)
{   int bit[14];
    int temp=k;
    if(dp[k]<inf)
    {
        return dp[k];
    }
    else
    {
        for(int i=0; i<12; i++)
        {
            bit[i]=(temp>>i)&1;
        }
        int Min=inf;
        for(int i=0; i<12; i++)
        {
            if(bit[i]==0)
            {
                if(i<=1)
                {
                    if(bit[i+1]==1&&bit[i+2]==1)
                    {
                        bit[i+1]=0;
                        bit[i+2]=0;
                        bit[i]=1;
                        copy(bit);
                        bit[i]=0;
                        bit[i+2]=1;
                        bit[i+1]=1;
                        int M=dfs(gert());
                        if(Min>M) Min=M;
                    }
                }
                else
                {
                    if(bit[i-2]==1&&bit[i-1]==1)
                    {
                        bit[i-2]=0;
                        bit[i-1]=0;
                        bit[i]=1;
                        copy(bit);
                        bit[i]=0;
                        bit[i-1]=1;
                        bit[i-2]=1;
                        int M=dfs(gert());
                        if(Min>M) Min=M;

                    }
                    if(bit[i+2]==1&&bit[i+1]==1&&(i+2)<12)
                    {
                        bit[i+2]=0;
                        bit[i+1]=0;
                        bit[i]=1;
                        copy(bit);
                        bit[i]=0;
                        bit[i+1]=1;
                        bit[i+2]=1;
                        int M=dfs(gert());
                        if(Min>M) Min=M;

                    }

                }
            }
        }
        if(Min==inf)
        {
            dp[k]=getcount(k);
        }
        else
        {
            dp[k]=Min;
        }
        return dp[k];
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s",text);
        memset(dp,0x3f,sizeof(dp));
        int tip=0;
        for(int i=0; i<12; i++)
        {
            if(text[i]=='-')
                tip<<=1;
            else
            {
                tip<<=1;
                tip|=1;
            }
        }
        dfs(tip);
        printf("%d\n",dp[tip]);

    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值