CF476B 1300

题意


输入 #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;
}
posted @   Isaac233  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示