题意
输入 #1
++-+-
+-+-+
输出 #1
1.000000000000
输入 #2
+-+-
+-??
输出 #2
0.500000000000
输入 #3
+++
??-
输出 #3
0.000000000000
解析
我是找规律做的。算出最后总体的差值x,求出有cnt个问号。
假设正数的数量是y,负数的数量则是cnt-y。
此时就是求|y-(cnt-y)| == x的解,y1 = (cnt-x)/2,y2 = (cnt+x)/2;可以发现cnt-x和cnt+x一定要能被2整除才行,也就是cnt和x奇偶性相同。
总共cnt个中选y1个当'+',那剩下的就是'-',取y2也是一样。就是个组合数C(cnt,y)。
求出组合数之后除以总体,2^cnt。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10,M = 1e6 + 10;
string s1,s2;
int n;
int main(){
cin >> s1;
int cnt = 0,cnt2 = 0,cnt1 = 0;
n = s1.size();
for(int i=0;i<n;i++){
if(s1[i] == '+'){
cnt1++;
}else{
cnt1--;
}
}
cin >> s2;
for(int i=0;i<n;i++){
if(s2[i] == '+') cnt2++;
else if(s2[i] == '-') cnt2--;
else cnt++;
}
int x = abs(cnt1 - cnt2);
// cout << x << endl;
if(x > cnt){
printf("%.12f",0.0);
}else{
//假设正数的数量是y,负数的数量则是cnt-y
//此时|y-(cnt-y)| == x的条件是 能被2整除
//y1 = (cnt-x)/2,y2 = (cnt+x)/2;
if((cnt - x) % 2){
printf("%.12f",0.0);
}else{
int res = max((cnt-x)/2,(cnt+x)/2);
// cout << res << endl;
double val = 1;
for(int i=cnt,j=1;i>=cnt-res+1&&j<=res;i--,j++){
val *= i;
val /= j;
}
for(int i=1;i<=cnt;i++) val /= 2;
printf("%.12f",val);
}
}
return 0;
}
//dp[i][j]表示走到第i个问号,坐标为j时的概率.因为坐标可能为负,所以数组前移10距离.
#include <bits/stdc++.h>
using namespace std;
double dp[40][40]={0};
string s,t;
int main(){
cout<<fixed<<setprecision(12);
cin>>s>>t;
int len=s.size();
int pos1=0,pos2=0,pos3=0;//跟上次a,b,n类似
for (int i=0;i<len;i++){
if(s[i]=='+') pos1++;
else pos1--;
if(t[i]=='+') pos2++;
else if (t[i]=='-') pos2--;
else pos3++;
}
dp[0+10][pos2+10]=1;
//将所有已经识别的信号扫过之后,也就是扫到第0个问号的所在的位置一定是pos2,因为整个dp都向右移了10格,所以要+10
for(int i=1;i<=pos3;i++)
for(int j=-10;j<=len;j++)
dp[i+10][j+10]=dp[i-1+10][j-1+10]*0.5+dp[i-1+10][j+1+10]*0.5;//dp状态转移,上面已经解释过了
cout<<dp[pos3+10][pos1+10];//输出扫完了所有问号位置pos1的概率
return 0;
}
标签:10,CF476B,1300,int,s1,cnt,y1,y2
From: https://www.cnblogs.com/dtdbm/p/17013861.html