The Water Bowls [POJ3185] [开关问题]
Posted ibilllee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了The Water Bowls [POJ3185] [开关问题]相关的知识,希望对你有一定的参考价值。
题意
一串长度为20的0,1数列,每次翻转i,会影响i-1,i+1,也被翻转,最少翻转成0的步骤数是多少?
Sample Input
0 0 1 1 1 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0
Sample Output
3
分析
这一道开关问题和POJ3276很类似,但是那个是有固定长度的,我们可以看做是一个点向后的一个区间进行翻转,就不会对前面产生影响.
这道题就不一样,会影响前面的,那我们就看做是i为作用点,i+1,i+2为附带效应点,就可以转换成上面那种类型了。只是要在位置0的地方枚举是否要翻转,在位置20判断。
代码
1 #include<set> 2 #include<map> 3 #include<queue> 4 #include<stack> 5 #include<cmath> 6 #include<cstdio> 7 #include<cstring> 8 #include<iostream> 9 #include<algorithm> 10 #define RG register int 11 #define rep(i,a,b) for(RG i=a;i<=b;++i) 12 #define per(i,a,b) for(RG i=a;i>=b;--i) 13 #define ll long long 14 #define inf (1<<29) 15 using namespace std; 16 int n,ans,A; 17 int num[25],f[25]; 18 inline int read() 19 { 20 int x=0,f=1;char c=getchar(); 21 while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} 22 while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} 23 return x*f; 24 } 25 26 int main() 27 { 28 freopen("a","r",stdin); 29 freopen("b","w",stdout); 30 n=20; 31 rep(i,1,20) num[i]=read(); 32 { 33 f[0]=1,A=1; 34 if((num[1]+f[0])&1) f[1]=1,A++; 35 rep(i,2,19) 36 if((f[i-1]+f[i-2]+num[i])&1) f[i]=1,A++; 37 if((f[19]+f[18]+num[20])&1) A=inf; 38 } 39 { 40 memset(f,0,sizeof(f)); 41 if((num[1]+f[0])&1) f[1]=1,ans++; 42 rep(i,2,n) 43 if((f[i-1]+f[i-2]+num[i])&1) f[i]=1,ans++; 44 if((f[19]+f[18]+num[20])&1) ans=inf; 45 } 46 if((f[18]+f[19]+num[20])&1)cout<<inf; 47 else cout<<min(ans,A); 48 return 0; 49 }
以上是关于The Water Bowls [POJ3185] [开关问题]的主要内容,如果未能解决你的问题,请参考以下文章
Greedy:The Water Bowls(POJ 3185)
The Water Bowls [POJ3185] [开关问题]