poj 3276 Face The Right Way 翻转问题的灵活处理

来源:互联网 发布:mysql for mac dmg 编辑:程序博客网 时间:2024/05/04 01:31

题意:

给一个0,1序列,每次连续翻转k个,求翻转m次将序列全置0的最优二元组(k,m)。

分析:

题意说是要优先优化m,但不一定要优先枚举m,可以先枚举k再在内循环中处理。这题关键是把独立关系转化为依赖关系,每位与前面一样为0,不一样为1。这样翻转一位i时,只需改变i+k,不用改变i,i+1,i+2,i+k-1。

代码:

//poj 3276//sep9//n^2#include <iostream>using namespace std;int a[5012],tmp[5012];int main(){int n;scanf("%d",&n);char pre,ch;pre='F';for(int i=1;i<=n;++i){scanf(" %c",&ch);if(ch==pre)a[i]=0;else a[i]=1;pre=ch;}int ans_k,ans_m=INT_MAX;for(int k=1;k<=n;++k){int sum=0;memcpy(tmp,a,sizeof(a));for(int i=1;i+k-1<=n;++i)if(tmp[i])++sum,tmp[i+k]^=1;for(int i=n-k+2;i<=n;++i){if(tmp[i]){sum=INT_MAX;break;}}if(sum<ans_m)ans_k=k,ans_m=sum;}printf("%d %d",ans_k,ans_m);return 0;} 
一开始写搓了一个,思维定式先枚举首要优化变量m去了:logn*n^3...

#include <iostream>using namespace std;const int MAXN=5012;int n;int a[MAXN],tmp[MAXN];int check(int operation){for(int k=1;k<=n;++k){int ok=1,cnt=0;for(int i=0;i<n;++i)tmp[i]=a[i];for(int i=0;i<n;){if(tmp[i]==0)++i;else{if(i+k>n){ok=0;break;} ++cnt;if(cnt>operation){ok=0;break;} for(int j=i;j<i+k;++j){tmp[j]^=1;}++i;} }if(ok==1)return k;}return 0;}int main(){scanf("%d",&n);char s[8];for(int i=0;i<n;++i){scanf("%s",s);if(s[0]=='B')a[i]=1;elsea[i]=0;}int K,M;int l=0,r=n+1;while(l<r){int mid=(l+r)/2;if(K=check(mid)){M=mid;r=mid;}elsel=mid+1;}printf("%d %d",K,M);return 0;} 




0 0