POJ3276 Face The Right Way 开关问题

①每个K从最左边进行考虑

②f[i]=[i,i+k-1]是否进行反转:1代表是,0代表否

∑ (i)(i=i+1-K+1) f[j]=∑ (i-1)(i=i-K+1) f[j]+f[i]-f[i-K+1]

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<queue>
 5 #include<map>
 6 #include<vector>
 7 #include<set>
 8 #include<string>
 9 #include<cmath>
10 #include<cstring>
11 using namespace std;
12 int n;
13 int dir[5005],f[5005];//dir牛的方向0F1B,f是[i,i-k+1]是否反转 
14 int cal(int k)//k求最小操作数 
15 {
16     memset(f,0,sizeof(f));
17     int res=0;
18     int sum=0;//f的和
19     for(int i=0;i+k<=n;i++)
20     {
21         if((dir[i]+sum)%2!=0)
22         {
23             res++;
24             f[i]=1;    
25         }    
26         sum+=f[i];
27         if(i-k+1>=0)
28         {
29             sum-=f[i-k+1];
30         }
31     }
32     //检查后面的牛有没有朝后 
33     for(int i=n-k+1;i<n;i++)
34     {
35         if((dir[i]+sum)%2!=0)
36         {
37             return -1;//无解 
38         }
39         if(i-k+1>=0)
40         {
41             sum-=f[i-k+1];
42         }
43     }
44     return res;
45 }
46 void solve()
47 {
48     int resK=1,resM=n;
49     for(int k=1;k<=n;k++)
50     {
51         int m=cal(k);
52         if(m>=0&&resM>m)
53         {
54             resM=m;
55             resK=k;
56         }
57     }
58     printf("%d %d\n",resK,resM);
59 }
60 int main()
61 {
62     scanf("%d",&n);
63     for(int i=0;i<n;i++)
64     {
65         getchar();
66         char c=getchar();
67         if(c=='B')
68             dir[i]=1;
69         else
70             dir[i]=0;
71     }
72     solve();
73     return 0;
74 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值