ARC132D-Between Two Binary Strings【贪心】
正題
題目鏈接:https://atcoder.jp/contests/arc132/tasks/arc132_d
題目大意
給出兩個恰好有nnn個111和mmm個000的字符串s,ts,ts,t,定義兩個字符串距離為通過交換兩個相鄰的字符把一個變成另一個的最小步數(shù)。
對于字符串kkk如果dis(s,k)+dis(k,t)=dis(s,t)dis(s,k)+dis(k,t)=dis(s,t)dis(s,k)+dis(k,t)=dis(s,t)那么kkk在s,ts,ts,t之間。
定義一個字符串的權(quán)值為相鄰的相同字符對數(shù)。
求所有在s,ts,ts,t之間的字符串中權(quán)值最大是多少。
1≤n+m≤3×1051\leq n+m\leq 3\times 10^51≤n+m≤3×105
解題思路
先考慮在s,ts,ts,t之間的字符串有什么性質(zhì),顯然的我們對于求dis(s,t)dis(s,t)dis(s,t)的時候最優(yōu)的策略肯定是把sss的第iii個111移動到ttt的第iii個111處。
也就是對于兩個串中第iii個111的位置記為x,yx,yx,y,那么就是一個一要從x→yx\rightarrow yx→y,也就是在s~ts\sim ts~t之間的字符串第iii個一肯定在x~yx\sim yx~y這個范圍。
這樣我們處理出每個111的合法區(qū)間li,ril_i,r_ili?,ri?,顯然的lil_ili?和rir_iri?必定遞增,因為交換兩個111的順序必定不劃算。所以可以考慮貪心。
不考慮邊界的問題,那么我們顯然要讓111的連續(xù)段盡量少,那么從小到大考慮l,rl,rl,r如果能和上一個放一起就放一起,不然就放在rrr的位置最賺。
然后考慮邊界,右邊界可以直接判斷因為我們肯定是盡量往右放的。左邊界的話我們?nèi)绻?span id="ze8trgl8bvbq" class="katex--inline">l1=1l_1=1l1?=1我們就分兩種情況考慮,也就是第一個放在左邊界和第一個放在r1r_1r1?兩種情況取個最大值。
時間復(fù)雜度:O(n+m)O(n+m)O(n+m)
code
#include<cstdio> #include<cstring> #include<algorithm> #define lowbit(x) (x&-x) using namespace std; const int N=6e5+10; int A,B,m,n,t[N],l[N],r[N],ans,prt; char a[N],b[N]; //void Change(int x,int val){ // while(x<=m){ // t[x]+=val; // x+=lowbit(x); // } // return; //} //int Ask(int x){ // int ans=0; // while(x){ // ans+=t[x]; // x-=lowbit(x); // } // return ans; //} int main() {scanf("%d%d",&A,&B);m=A+B;scanf("%s",a+1);scanf("%s",b+1);for(int i=1;i<=m;i++)if(a[i]=='1')l[++n]=i;n=0;for(int i=1;i<=m;i++)if(b[i]=='1')r[++n]=i;for(int i=1;i<=n;i++){if(l[i]>r[i])swap(l[i],r[i]);}int last=-1;for(int i=1;i<=n;i++){if(l[i]<=last+1)last++;else ans++,last=r[i];}ans=ans*2;if(last!=m)ans++;prt=m-ans;if(l[1]==1){last=1;ans=1;for(int i=2;i<=n;i++){if(l[i]<=last+1)last++;else ans+=2,last=r[i];}if(last!=m)ans++;ans=m-ans;prt=max(prt,ans);}printf("%d\n",prt);return 0; }總結(jié)
以上是生活随笔為你收集整理的ARC132D-Between Two Binary Strings【贪心】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 美服炉石传说安卓下载(炉石传说 安卓下载
- 下一篇: qq怎么创建提醒(怎么添加qq提醒)