Pebble Solitaire+uva+狀態壓縮+記憶化搜尋
Time Limit: 3000MS | Memory Limit: Unknown | 64bit IO Format: %lld & %llu |
Description
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
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 '-'
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;
}