HDU2209 翻紙牌遊戲 (DFS)
阿新 • • 發佈:2018-12-13
題目連結:點這裡
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; }