UVA 10651 --Pebble Solitaire +dfs

这道题有两种做法:搜索和状态压缩dp

因为这个题的状态只要2^12,所以可以用dfs或bfs将所有的可达状态走一遍,然后就可以得到答案了。

我是用二进制压缩以后再进行的dfs;其实也可以直接开一个12位长度数组表示状态,然后dfs或bfs,这样

状态判重可以用hash或二进制压缩。

状态压缩dp的话,现在还没看,就放到以后再研究去了。

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

int vis[5000],ans;

void dfs(int st)
{
    int a[20];
    int k=0;
    memset(a,0,sizeof(a));
    while(st)
    {
        a[k++]=st%2;
        st/=2;
    }
    k=12;
    for(int i=k-1;i>=2;i--)
    {
        if(a[i]==0&&a[i-1]==1&&a[i-2]==1)
        {
            int b[30];
            for(int j=0;j<k;j++)
               b[j]=a[j];
            b[i]=1; b[i-1]=0; b[i-2]=0;
            int cnt=0,sum=0;
            for(int j=k-1;j>=0;j--)
            {
                if(b[j]==1)
                  cnt++;
                if(b[j]==1)
                  sum=sum*2+1;
                else
                  sum=sum*2;
            }
            if(cnt!=0&&cnt<ans)
                 ans=cnt;
            if(vis[sum]==0)
            {
                 vis[sum]=1;
                 dfs(sum);
            }
        }
    }
    for(int i=0;i<k-2;i++)
    {
        if(a[i]==0&&a[i+1]==1&&a[i+2]==1)
        {
            int b[30];
            for(int j=0;j<k;j++)
               b[j]=a[j];
            b[i]=1; b[i+1]=0; b[i+2]=0;
            int cnt=0,sum=0;
            for(int j=k-1;j>=0;j--)
            {
                if(b[j]==1)
                  cnt++;
                if(b[j]==1)
                  sum=sum*2+1;
                else
                  sum=sum*2;
            }
            if(cnt!=0&&cnt<ans)
                 ans=cnt;
            if(vis[sum]==0)
            {
                 vis[sum]=1;
                 dfs(sum);
            }
        }
    }
}

int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        ans=0;
        char str[20];
        scanf("%s",str);
        int len=strlen(str);
        int st=0;
        for(int i=0;i<len;i++)
        {
            if(str[i]=='o')
               ans++;
            if(str[i]=='o')
               st=st*2+1;
            else
               st=st*2;
        }
        memset(vis,0,sizeof(vis));
        vis[st]=1;
        dfs(st);
        printf("%d\n",ans);
    }
  return 0;
}
时间: 2024-08-12 04:50:03

UVA 10651 --Pebble Solitaire +dfs的相关文章

uva 10651 Pebble Solitaire (BFS)

uva 10651 Pebble Solitaire 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

UVa 10651 Pebble Solitaire(DP 记忆化搜索)

Pebble Solitaire 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

UVA 10651 Pebble Solitaire(记忆化)

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. P

UVa 10651 Pebble Solitaire (DP 卵石游戏 记忆化搜索)

 题意  给你一个长度为12的字符串  由字符'-'和字符'o'组成  其中"-oo"和"oo-"分别可以通过一次转换变为"o--"和"--o"  可以发现每次转换o都少了一个  只需求出给你的字符串做多能转换多少次就行了 令d[s]表示字符串s最多可以转换的次数  若s可以通过一次转换变为字符串t  有d[s]=max(d[s],d[t]+1) #include<iostream> #include<s

UVa 10651 - Pebble Solitaire

题目:有一个类似跳棋的游戏,一共有12个位置'o'代表棋子'-'代表空位, 'oo-'可以转化成'--o','-oo'可以转化成'o--',给你初始状态,问最后,至少剩下几个棋子. 分析:dp,记忆化搜索,位运算.利用搜索在相邻状态间dp即可. 每个状态的最优解为他能转化所有状态中的最优解. 因为,一共有2^12 = 4096个状态,每次找到解即存储,不会重复计算,所以时间方面没问题. 利用一个12位整数表示一个状态,'o'用1表示,'-'用0表示,则'---oo-------'为24(2进制0

UVa 10651 Pebble Solitaire(状态压缩DP)

题意:转化为01序列,可以做如下转换011–>100, 110–>001 使得序列的1最少 二进制的集合表示: 空集:0 全集:( 1< #include<iostream> #include<algorithm> #include<map> #include<cstdio> #include<cstdlib> #include<vector> #include<cmath> #include<cs

【UVA】10651-Pebble Solitaire(直接递归或者记忆化)

不知道这个题UVA的数据是怎么的,用2个方法交了,第一次直接递归,第二次记忆化剪枝,时间竟然一样!? 直接郁闷了,简单的二进制表示状态和二进制运算. 14145176 10651 Pebble Solitaire Accepted C++ 0.009 2014-09-04 09:18:21 #include<cstdio> #include<algorithm> #include<string> #include<cstring> #include<m

UVa 572 Oil Deposits(DFS)

 Oil Deposits  The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots.

UVA 10318 - Security Panel dfs 剪枝

UVA 10318 - Security Panel dfs 剪枝 ACM 题目地址:UVA 10318 - Security Panel 题意: 这题跟点灯的题目很像,点灯游戏选择一盏灯时会让它以及四周的灯改变状态. 但是我们有特殊的开开关技巧,它给出了改变状态的位置,而不是四周都改变. 问你从全部关着变成全部开着的最小开关步骤. 分析: 很明显,在一个位置上点两次或更多次是没有必要的,所以一个位置只有选择与不选择,用dfs即可,但如果暴力所有可能,复杂度是2^25,会超时,所以要剪枝. 由于