zoukankan      html  css  js  c++  java
  • (dp)AtCoder Grand Contest 019 D

    D - Shift and Flip


    Time limit時間制限 : 2sec / Memory limitメモリ制限 : 256MB

    配点 : 1000

    問題文

    01 からなる同じ長さの二つの文字列 A=A1A2AnB=B1B2Bn があります。

    あなたは、以下の操作を任意の順序で何度でも行って A を変化させることができます。

    • A を一文字左にシフトする(すなわち、A=A1A2An として AA2A3AnA1 に置き換える)。
    • A を一文字右にシフトする(すなわち、A=A1A2An として AAnA1A2An−1 に置き換える)。
    • Bi=1 であるような i をいずれか一つ選び、Ai を反転する(すなわち、Ai=1−Ai とする)。

    あなたの目標は文字列 A,B を一致させることです。

    これに必要な最小の操作回数を出力してください。ただし、これが不可能である場合は −1 と出力してください。

    制約

    • 1≤|A|=|B|≤2,000
    • A,B01 からなる。

    入力

    入力は以下の形式で標準入力から与えられる。

    A
    B
    

    出力

    文字列 A,B を一致させるために必要な最小の操作回数を出力せよ。ただし、これが不可能である場合は −1 と出力せよ。


    入力例 1

    Copy
    1010
    1100
    

    出力例 1

    Copy
    3
    

    目標を達成する最短の操作列を一つ示します。

    • A1 を反転: A=0010
    • A を左にシフト: A=0100
    • A1 を再度反転: A=1100

    入力例 2

    Copy
    1
    0
    

    出力例 2

    Copy
    -1
    

    A の唯一のビットを反転させる方法はありません。


    入力例 3

    Copy
    11010
    10001
    

    出力例 3

    Copy
    4
    

    目標を達成する最短の操作列を一つ示します。

    • A を右にシフト: A=01101
    • A5 を反転: A=01100
    • A を左にシフト: A=11000
    • A を再度左にシフト: A=10001

    入力例 4

    Copy
    0100100
    1111111
    

    出力例 4

    Copy
    5
    

    A1, A3, A4, A6, A7 を任意の順序で反転すればよいです。

    Score : 1000 points

    Problem Statement

    You have two strings A=A1A2An and B=B1B2Bn of the same length consisting of 0 and 1.

    You can transform A using the following operations in any order and as many times as you want:

    • Shift A by one character to the left (i.e., if A=A1A2An, replace A with A2A3AnA1).
    • Shift A by one character to the right (i.e., if A=A1A2An, replace A with AnA1A2An−1).
    • Choose any i such that Bi=1. Flip Ai (i.e., set Ai=1−Ai).

    You goal is to make strings A and B equal.

    Print the smallest number of operations required to achieve this, or −1 if the goal is unreachable.

    Constraints

    • 1≤|A|=|B|≤2,000
    • A and B consist of 0 and 1.

    Input

    Input is given from Standard Input in the following format:

    A
    B
    

    Output

    Print the smallest number of operations required to make strings A and B equal, or −1 if the goal is unreachable.


    Sample Input 1

    Copy
    1010
    1100
    

    Sample Output 1

    Copy
    3
    

    Here is one fastest way to achieve the goal:

    • Flip A1: A=0010
    • Shift A to the left: A=0100
    • Flip A1 again: A=1100

    Sample Input 2

    Copy
    1
    0
    

    Sample Output 2

    Copy
    -1
    

    There is no way to flip the only bit in A.


    Sample Input 3

    Copy
    11010
    10001
    

    Sample Output 3

    Copy
    4
    

    Here is one fastest way to achieve the goal:

    • Shift A to the right: A=01101
    • Flip A5: A=01100
    • Shift A to the left: A=11000
    • Shift A to the left again: A=10001

    Sample Input 4

    Copy
    0100100
    1111111
    

    Sample Output 4

    Copy
    5
    

    Flip A1, A3, A4, A6 and A7 in any order.

    整个过程为序列向左、向右移动,以及单独修改某一个位置。故在此过程中存在最左移动的值,最右移动的值,以及最终的位移量。

    显然根据单独修改的条件,对B为全是0的串需要单独判断。

    之后枚举d(分别为向左、向右移动0——len-1)每一次计算当下的最优L、R(最左、最右移动的值),该值需满足所有与对应最终位置的Bi不同的Ai要经过过至少1次“1”。

    为此可以简单的dp一下,即可在O(n)时间内求出。故整体时间复杂度为O(n^2)

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <set>
      6 #include <map>
      7 #include <string>
      8 #include <cstring>
      9 #include <stack>
     10 #include <queue>
     11 #include <cmath>
     12 #include <ctime>
     13 #include<bitset>
     14 #include <utility>
     15 using namespace std;
     16 #define rank rankk
     17 #define mp make_pair
     18 #define pb push_back
     19 #define xo(a,b) ((b)&1?(a):0)
     20 //#define LL ll
     21 typedef unsigned long long ull;
     22 typedef pair<int,int> pii;
     23 typedef long long ll;
     24 typedef pair<ll,int> pli;
     25 const int INF=0x3f3f3f3f;
     26 const ll INFF=0x3f3f3f3f3f3f3f3fll;
     27 //#define xs1 xs
     28 //#define xs2 x
     29 //const ll M=1e9+7;
     30 //const ll maxn=2e5+7;
     31 //const int MAXN=1005;
     32 const int MAX=2e3+5;
     33 const int MAX_N=MAX;
     34 //const int N=55;
     35 const ll MOD=1000000007;
     36 const long double pi=acos(-1.0);
     37 //const double eps=0.00000001;
     38 int gcd(int a,int b){return b?gcd(b,a%b):a;}
     39 template<typename T>inline T abs(T a) {return a>0?a:-a;}
     40 template<class T> inline
     41 void read(T& num) {
     42     bool start=false,neg=false;
     43     char c;
     44     num=0;
     45     while((c=getchar())!=EOF) {
     46         if(c=='-') start=neg=true;
     47         else if(c>='0' && c<='9') {
     48             start=true;
     49             num=num*10+c-'0';
     50         } else if(start) break;
     51     }
     52     if(neg) num=-num;
     53 }
     54 inline ll powMM(ll a,ll b,ll M){
     55     ll ret=1;
     56     a%=M;
     57 //    b%=M;
     58     while (b){
     59         if (b&1) ret=ret*a%M;
     60         b>>=1;
     61         a=a*a%M;
     62     }
     63     return ret;
     64 }
     65 void open()
     66 {
     67     freopen("1009.in","r",stdin);
     68     freopen("out.txt","w",stdout);
     69 }
     70 char a[MAX],b[MAX];
     71 int l[MAX],r[MAX],len,an,cnt,tem;
     72 int x[MAX];//在某个x时最大的y
     73 int main()
     74 {
     75     scanf("%s%s",a,b);an=INF;
     76     len=strlen(a);
     77     bool st1,st2;st1=st2=true;
     78     for(int i=0;i<len&&st1;i++)if(a[i]=='1')st1=false;
     79     for(int i=0;i<len&&st2;i++)if(b[i]=='1')st2=false;
     80     if(st2)
     81     {
     82         if(st1)printf("0
    ");else printf("-1
    ");return 0;
     83     }
     84     for(int i=0;i<len;i++)
     85     {
     86         int j=0;
     87         for(;b[(i+j)%len]!='1';)++j;
     88         r[i]=j;
     89     }
     90     for(int i=0;i<len;i++)
     91     {
     92         int j=0;for(;b[(i-j+len)%len]!='1';)++j;
     93         l[i]=j;
     94     }
     95     for(int d=0;d<len;d++)//枚举d
     96     {
     97         cnt=0;tem=INF;memset(x,0,sizeof(x));
     98         //最终向右移动
     99         for(int i=0;i<len;i++)
    100         {
    101             if(a[i]!=b[(i+d)%len]){
    102                     ++cnt;
    103                     if(r[i]<=d)continue;//不需要加
    104                     x[l[i]]=max(x[l[i]],r[(i+d)%len]);
    105             }
    106         }
    107         for(int i=len-1;i>=0;i--){
    108                 x[i]=max(x[i],x[i+1]);
    109                 tem=min(x[i+1]+i,tem);
    110         }
    111         an=min(an,2*tem+d+cnt);
    112         //最终向左移动
    113         cnt=0;tem=INF;memset(x,0,sizeof(x));
    114         for(int i=0;i<len;i++)
    115         {
    116             if(a[i]!=b[(i-d+len)%len])
    117             {
    118                 ++cnt;
    119                 if(l[i]<=d)continue;//不需要加
    120                 x[l[(i-d+len)%len]]=max(x[l[(i-d+len)%len]],r[i]);
    121             }
    122         }
    123         for(int i=len-1;i>=0;i--)
    124         {
    125             x[i]=max(x[i],x[i+1]);
    126             tem=min(x[i+1]+i,tem);
    127         }
    128         an=min(an,2*tem+d+cnt);
    129     }
    130     printf("%d
    ",an);
    131     return 0;
    132 }
  • 相关阅读:
    【反演复习计划】【bzoj2154】Crash的数字表格
    【反演复习计划】【bzoj3529】数表
    【反演复习计划】【bzoj3994】DZY loves maths
    【反演复习计划】【bzoj3994】约数个数和
    【反演复习计划】【bzoj2818】gcd
    【反演复习计划】【bzoj1011】zap-queries
    BZOJ3991: [SDOI2015]寻宝游戏
    BestCoder Round #75
    BZOJ4417: [Shoi2013]超级跳马
    BZOJ4416: [Shoi2013]阶乘字符串
  • 原文地址:https://www.cnblogs.com/quintessence/p/7455681.html
Copyright © 2011-2022 走看看