码迷,mamicode.com
首页 > 其他好文 > 详细

UVa 10651 Pebble Solitaire(状态压缩DP)

时间:2015-07-29 19:18:38      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:uva10651

题意:转化为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
*/









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

UVa 10651 Pebble Solitaire(状态压缩DP)

标签:uva10651

原文地址:http://blog.csdn.net/u013167299/article/details/47131855

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!