1. 程式人生 > >HDU2209 翻紙牌遊戲 (DFS)

HDU2209 翻紙牌遊戲 (DFS)

題目連結:點這裡

Problem Description

有一種紙牌遊戲,很有意思,給你N張紙牌,一字排開,紙牌有正反兩面,開始的紙牌可能是一種亂的狀態(有些朝正,有些朝反),現在你需要整理這些紙牌。但是麻煩的是,每當你翻一張紙牌(由正翻到反,或者有反翻到正)時,他左右兩張紙牌(最左邊和最右邊的紙牌,只會影響附近一張)也必須跟著翻動,現在給你一個亂的狀態,問你能否把他們整理好,使得每張紙牌都正面朝上,如果可以,最少需要多少次操作。

Input

有多個case,每個case輸入一行01符號串(長度不超過20),1表示反面朝上,0表示正面朝上。

Output

對於每組case,如果可以翻,輸出最少需要翻動的次數,否則輸出NO。

Sample Input

01 011

Sample Output

NO 1

PS:這個題還是很經典的一個題,首先應該從前面往後面分析。首先分析第一張翻不翻,要是第一張要翻的話,只能翻第一張和第二張兩種情況,然後後面可以根據前面的得出翻不翻。

#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<stack>
#include<string>
const int maxn=1e4+10;
const int mod=1e9+7;
const int inf=1e8;
#define me(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&(-x)
typedef long long ll;
using namespace std;
int a[30];
int dfs(int x,int len,int step)
{
    if(x==len)
        return a[x-1]?inf:step;
    if(a[x-1])
        a[x-1]=0,a[x]=!a[x],a[x+1]=!a[x+1],step++;
    return dfs(x+1,len,step);
}
int main() 
{
    string s;
    while(cin>>s)
    {
        for(int i=0;i<s.size();i++)
            a[i]=s[i]-'0';
        int sum=inf;
        sum=min(sum,dfs(1,s.size(),0));
        for(int i=0;i<s.size();i++)
            a[i]=s[i]-'0';
        a[0]=!a[0],a[1]=!a[1];
        sum=min(sum,dfs(1,s.size(),1));
        if(sum==inf)
            cout<<"NO"<<endl;
        else
            cout<<sum<<endl;
    }
    return 0;
}