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<cstring>
#include<stack>
#include<string>
#include<set>
#include<fstream>
using namespace std;
#define pb push_back
#define cl(a,b) memset(a,b,sizeof(a))
#define bug printf("===\n");
#define rep(a,b) for(int i=a;i<b;i++)
#define rep_(a,b) for(int i=a;i<=b;i++)
#define P pair<int,int>
#define X first
#define Y second
#define vi vector<int>
const int maxn=12;
const int inf=999999999;
typedef long long LL;
void Max(int&a,int b){if(a<b)a=b;}
void Min(int&a,int b){if(a>b)a=b;}

char a[maxn];
int dp[(1<<maxn)+1000];
int dfs(int n){
    if(dp[n]!=-1)return dp[n];
    dp[n]=0;
    for(int i=0;i<12;i++)if(n&(1<<i))dp[n]++;
    for(int i=0;i<10;i++){
        int t=n;
        if((t&(1<<i))&&(t&(1<<(i+1)))&&!(t&(1<<(i+2)))){//011
            t&=~(1<<i);
            t&=~(1<<(i+1));
            t|=(1<<(i+2));//把序列的011换为100
            Min(dp[n],dfs(t));
        }
        t=n;
        if((t&(1<<(i+2)))&&(t&(1<<(i+1)))&&!(t&(1<<i))){//110
            t|=(1<<i);
            t&=~(1<<(1+i));
            t&=~(1<<(i+2));//把序列的110换为001
            Min(dp[n],dfs(t));
        }
    }
    return dp[n];
}

int main(){
    int n;
    cl(dp,-1);
    cin>>n;
    while(n--){
        int x=0;
        scanf("%s",a);
        for(int j=0;j<12;j++)if(a[j]==‘o‘){
            x|=(1<<j);
        }
        printf("%d\n",dfs(x));
    }

    return 0;
}

/*
5
---oo-------
-o--o-oo----
-o----ooo---
oooooooooooo
oooooooooo-o
*/

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2025-01-04 05:28:43

UVa 10651 Pebble Solitaire(状态压缩DP)的相关文章

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 +dfs

这道题有两种做法:搜索和状态压缩dp 因为这个题的状态只要2^12,所以可以用dfs或bfs将所有的可达状态走一遍,然后就可以得到答案了. 我是用二进制压缩以后再进行的dfs:其实也可以直接开一个12位长度数组表示状态,然后dfs或bfs,这样 状态判重可以用hash或二进制压缩. 状态压缩dp的话,现在还没看,就放到以后再研究去了. 代码如下: #include<iostream> #include<cstring> #include<cstdio> using na

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 (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(记忆化)

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

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

UVA 1252-Twenty Questions(状态压缩DP+子集枚举)

题目大意:有n个物品,每个物品有m个特征,每个物品的每个特征都可能有或没有,现在假定某个物品,通过询问某些特征来确定这个物品,问最多需要多少次就可以确定物品. 每次询问之后可能根据答案不同来采取不同的进一步询问的策略. 用d[S][S0]表示目前询问了S,得到的回答是S0(即那个物品在S中有S0这些特征),最少还需询问多少次.枚举下一次询问的特征完成递推.最终d[0][0]就是答案.S0显然是S的一个子集.下一次询问的特征不是S已有的特征.如果对于某个d[S][S0]只有一个物品满足,那么此时值

UVA 1633-Dyslexic Gollum(状态压缩DP)

题目大意:求长度为N(1<=N<=400)且不含长度大于或等于K(1<=K<=10)的回文串的01串. 用d[i][j][u]表示长度为i且后11个01串组成数j且不含长度大于或等于u的01串有多少个. 如果j中含有长度至少为u的回文串,那么d[i][j][u]=0. 否则,假设d[i][j][u]可以由d[i-1][v][u]转移得来.根据状态的表示,那么v的低10位肯定是u的高10位,v的最高一位可以为0或1,即v=j/2或v=j/2+(1<<10). 程序将表打出

UVA 11825 - Hackers&amp;#39; Crackdown 状态压缩 dp 枚举子集

UVA 11825 - Hackers' Crackdown 状态压缩 dp 枚举子集 ACM 题目地址:11825 - Hackers' Crackdown 题意: 有一个由编号0~n-1的n台计算机组成的网络,一共同拥有n种服务,每台计算机上都执行着所有服务,对于每台计算机,你能够选择停止一项服务,这个行为会导致与这台计算机和与他相连的其它计算机上的这项服务都停止(原来已经停止的继续保持停止状态). 求最多能使多少个服务瘫痪(即没有不论什么一台计算机在执行这项服务). 分析: 题目说白了.就