日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

北邮OJ 1010. 16校赛-Binary Strings

發布時間:2024/9/30 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 北邮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(1T50? ), indicating the number of test cases. For each test case, the first line contains one integers?N(1N100000), 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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。