北邮OJ 1010. 16校赛-Binary Strings
時間限制?5000 ms?內存限制?65536 KB
題目描述
?? ?One day, the teacher asked Weishen to judge whether a binary string can be divided by 3?(3=(11)2)?in binary system.?
?? ?"It’s too simple.", Weishen said, and solved it quickly.?
?? ?Teacher was very angry, he decided to teach Weishen some life experience.
?? ?So he added '?' characters to the 01 string, '?' can replace either 0 or 1 respectively. ?
?? ?This time he askes Weishen to calculate the expected number of substrings that can be divided by 3 if each '?' randomly replaces '0' or '1'. Note that the substrings can not contain leading zeroes, thus you should ignore substrings like?(011)2. Weishen would like you to help him solve this problem.
?
輸入格式
?? ?The input begins with a line containing a single integer?T(1≤T≤50? ), indicating the number of test cases. For each test case, the first line contains one integers?N(1≤N≤100000), indicating the length?of the string. The next lines is the string containing?Ncharacters given by the teacher. It is guaranteed that only characters '0', '1', and '?' would appear in the strings.
輸出格式
For each?case, please output?a line containing a?real number?rounded to the second decimal?place, indicating the answer.?
Explanation?of?example
For the first case '01?', if this '?' represent '0', then we get '010', there are two substrings divisible by 3: '0' and '0'. If this '?' represent '1', we get '011' and there are also two substrings divizible by 3: '0' and '11'. String '011'has leading zeroes and we have to omit it. The expected number of substrings will be (2+2)/2=2.
輸入樣例
1 3 01?輸出樣例
2.00 題意是給你一個長度最大10^5的二進制01串,其中有些位置被?模糊了,問所有的可能性里,所有的能被3整除的子串的數量的期望值是多少,期望DP。樣例解釋:01?
0.5概率?是1, 011里,0和11都可以被3整除
0.5概率?是0, 010里,第一個0和第三個0都可以被3整除
所以0.5*2+0.5*2=2
因為要求被3整除,所以設dp[100000+5][3],dp[i][j]表示以i位結尾的模3余數為j的子串的數量有多少。
然后有12種狀態轉移,null代表開頭第一位前面沒有字符,其余的都代表由前一位轉移到當前位的字符變化情況
null->0,null->1,null->?
0->0,0->1,0->?
1->0,1->1,1->?
?->0,?->1,?->?
我們知道,對元二進制串A后加一位0意味著A*2,根據模運算
①A%3==1,(A*2)%3==2
②A%3==2,(A*2)%3==1
③A%3==0,(A*2)%3==0所以狀態轉移方程里,轉移到當前位是0的情況里,一定都都要有dp[i][1]=dp[i-1][2], ?dp[i][2]=dp[i-1][1]
我們又知道,對元二進制串A后加一位1意味著A*2+1,根據模運算
①A%3==1,(A*2+1)%3==0
②A%3==2,(A*2+1)%3==2
③A%3==0,(A*2+1)%3==1轉移到當前位是1的情況里,一定都要有dp[i][2]=dp[i-1][2], dp[i][0]=dp[i-1][1]
然后我們具體來看各個轉移
1.我們來看0->0的情況顯然,以前一個0結尾的可以被3整除的數,*2還是可以被整除,所以dp不變,比如110,1100,以第三位結尾的有110、0,以第4位結尾的,1100、0,沒有任何變化。dp[i][0]=dp[i-1][0]
2.再來看1->0的情況,顯然以前一個1結尾的可以被3整除的數,*2還是可以被整除,但新增加了一個單個的0,所以dp+1,dp[i][0]=dp[i-1][0]+1
3.如果是?->0的話,顯然0->0和1->0各占50%,dp+0.5,dp[i][0]=dp[i-1][0]+0.5
4.如果是null->0的話,顯然+1,因為增加了單個0.
我們再來看->1的情況,因為前一位%3==1和%3==2的情況的情況都講明了,所以在此只看%3==0的部分
5.我們來看0->1的情況,*2+1,舉個例子,100->1001, dp[3][0]=1, dp[4][1]=1,?dp[i][1]=dp[i-1][0]
6.1->1的情況,舉個例子,101->1011,dp[3][0]=0, dp[4][1]=1, dp[i][1]=dp[i-1][0]+1, 為什么都是*2+1,它卻要額外dp+1呢,因為1變成11, 11可以被3整除,所以要+1
7.如果是?->1的話,顯然dp+0.5,dp[i][0]=dp[i-1][0]+0.5
然后字符->?后續的情況把上面都加概率仔細算一下就好
代碼略長
#include<cstdio> #include<cmath> #include<algorithm> #define N 100050 using namespace std; char str[N]; double dp[N][3]; int main(){int t,n,i;for(scanf("%d",&t);t--;){scanf("%d",&n);scanf("%s",str+1);dp[0][0]=dp[0][1]=dp[0][2]=0;str[0]='Z';double res=0;for(i=1;i<=n;i++){if(str[i]=='0'){if(str[i-1]=='0'){dp[i][0]=dp[i-1][0];}else if(str[i-1]=='1'){dp[i][0]=dp[i-1][0]+1;}else if(str[i-1]=='?'){dp[i][0]=dp[i-1][0]+0.5;}else {dp[i][0]=dp[i-1][0]+1;}dp[i][1]=dp[i-1][2];dp[i][2]=dp[i-1][1];}else if(str[i]=='1'){if(str[i-1]=='0'){dp[i][1]=dp[i-1][0];}else if(str[i-1]=='1'){dp[i][1]=dp[i-1][0]+1;//*2+1,1mod 3==1}else if(str[i-1]=='?'){dp[i][1]=dp[i-1][0]+0.5;}else{dp[i][1]=dp[i-1][0]+1;}dp[i][2]=dp[i-1][2];dp[i][0]=dp[i-1][1];//no add 0}else {dp[i][0]=0.5*dp[i-1][1];dp[i][1]=0.5*dp[i-1][2];dp[i][2]=0.5*dp[i-1][1]+0.5*dp[i-1][2];if(str[i-1]=='0'){dp[i][0]+=dp[i-1][0]*0.5;dp[i][1]+=dp[i-1][0]*0.5;}else if(str[i-1]=='1'){dp[i][0]+=(dp[i-1][0]+1)*0.5;dp[i][1]+=(dp[i-1][0]+1)*0.5;}else if(str[i-1]=='?'){dp[i][0]+=(dp[i-1][0]+0.5)*0.5;dp[i][1]+=(dp[i-1][0]+0.5)*0.5;}else{dp[i][0]+=(dp[i-1][0]+1)*0.5;dp[i][1]+=(dp[i-1][0]+1)*0.5;}}}for(i=1;i<=n;i++)res=res+dp[i][0];printf("%.2lf\n",res);}return 0; }
總結
以上是生活随笔為你收集整理的北邮OJ 1010. 16校赛-Binary Strings的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 北邮OJ 1005. 16校赛-Hawe
- 下一篇: 北邮OJ 1021. 16校赛-Ston