Hackerrank-"String transmission"

Source: Internet
Author: User

Classic and challenging dp! And you need combine several tricks together with DP-make it 100% pass.

My Main reference is here:https://github.com/havelessbemore/hackerrank/blob/master/algorithms/bit_manipulation/ String-transmission.java

Basically it is a counting problem. It's easy-to-possible count should be SUM (CR (n, 0), CR (n, 1),.. Cr (n, k)) without the limitation of "No Periodic strings". And then we can count how many "periodic" strings there is. DP is useful here-two states:length of the current substr, and number of corrupted bits, dp[ending index][no. of corrupted bits]. We can go index by index. Grab This fact in your mind: periodic strings <=> all Char[i + divisor * t] is identical, so in case there is different digits in [I, i + D, I + 2d ...], we can either flip 0s or 1s. Each flipping would increase the 2nd state: "Number of corrupted bits". Since indexes is independent with each other, we can simply use "+" to advance in the DP.

Optimization:dp[len + 1] only depends on Dp[len], we can use Rolling-array. Oh another one, to get Cr (n, k), Pascal's Triangle is a good choice here.

#include <iostream>#include<string>#include<vector>#include<unordered_map>using namespacestd;#defineMax_len 1001#defineMOD 1000000007inlineintMoDintnum) {    return(num% mod + MoD)%MOD;}intMain () {//Pascal ' s Triangle to compute Cr (n, k)vector<vector<int>> cr (Max_len, vector<int> (Max_len,0)); cr[0][0] =1;  for(inti =1; i < Max_len; i + +) {cr[i][0] =1;  for(intj =1; J <= I; J + +) Cr[i][j]= MoD (Cr[i-1][j-1] + cr[i-1][j]); }        //    intT CIN >>T;  while(t--)    {        intN, K; CIN >> N >>K; stringStr CIN >>str; intLen =str.length (); //Original Total:sum (CR (n, 0), CR (n, 1), CR (n, 2),.. Cr (n, k))        intRET =0;  for(inti =0; I <= K; i + +) ret= MoD (ret +Cr[len][i]); //Get all divisorsvector<int>Divisor;  for(intD =1; D < Len; D + +)            if(len% d = =0) Divisor.push_back (d); BOOLbselfrepeated =false; //DPvector<vector<int>> DP (Divisor.size (), vector<int> (Max_len + k,0)); //For each divisor :         for(intID =0; ID < divisor.size (); ID + +)        {            intD =Divisor[id]; /*             * Original DP: * dp[substr_ending_index][corrupted bits No.] = No.  of repeated string, where * Dp[len + 1][cnt + zerocnt] + = dp[len][cnt] "for flipping             0s "* dp[len + 1][cnt + len/divisor-zerocnt] + + dp[len][cnt]" for flipping 1s "* * idea was like this:for a repeated string [pattern]+, all terms above was for pattern only le N is the ending substr index into pattern.                We Check index by index within this pattern. For each divisor-th sequence, (i, i + D, i + 2d ...), we can simply the flip the zeros in it to make chars at (i , i + D, i + 2d ...)                Identical to all 1, and so does for flipping 1s (2nd equation above). Now, let's check DP State at index (i + 1).  Say at index i (i + 1, i + 1 + d, i + 1 + 2d ...), number of zeros is zerocnt, then the CNT of Dp[i + 1] can be built upon Dp[i], for each of (0..K)Of course Since each index are independent with each other, it is simply "+" upon the previous count.              * If you want-get 100% pass, you have to apply rolling array optimization, as below*/                    //DP Startdp[id][0] =1;  for(intj =0; J < D; J + +)            {                //counting Zeros                intzerocnt =0;  for(inti = j; i < Len; i + =d)if(Str[i] = ='0') zerocnt + +; Vector<int> Pre =Dp[id]; Std::fill (Dp[id].begin (), Dp[id].end (),0);  for(inti =0; I <= K; i + +)                {                    if(Pre[i] >0) {Dp[id][i+ zerocnt] = mod (dp[id][i + zerocnt] + pre[i]);//for flipping 0sDp[id][i + len/d-zerocnt] = mod (dp[id][i + len/d-zerocnt] + pre[i]);//for flipping 1s                    }                }            }            if(dp[id][0] >0) bselfrepeated =true; //Avoid Duplicated counting             for(intPID =0; PID < ID; PID + +)                if(d% divisor[pid] = =0)                     for(inti =0; I <= K; i + +) dp[id][i] = mod (Dp[id][i]-Dp[pid][i]); //repeated string number counting done. //Now removing No. of repeated pattern strings             for(inti =1; I <= K; i + +) ret= MoD (ret-Dp[id][i]); }        //If Input str itself is in repeated pattern.        if(bselfrepeated) ret = mod (ret-1); cout<< ret <<Endl; }//While (t--)    return 0;}

Hackerrank-"String transmission"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.