F: 抛硬币

Description
James得到了一堆有趣的硬币,于是决定用这些硬币跟朋友们玩个小游戏。在一个N行M列的表格上,每一个第i行第j列的格子上都放有一枚James的硬币,抛该硬币正面朝上的概率为Pij,所有抛硬币事件两两之间是相互独立的。
现在,玩家在M列硬币中,从每一列里各选择1枚,共M枚,构成一组。如此重复选择N组出来,且保证被选择过的硬币不能再选。选好组之后,每组的M枚硬币各抛一次,如果都是正面朝上,则该组胜利,总分赢得1分;否则该组失败,总分不加也不减。请问,如果让你自行选择硬币的分组,游戏总得分的数学期望的最大值是多少?
Input
输入有多组数据。每组数据第一行为N和M,1≤N≤100,1≤M≤10,以空格分隔。接下来有N行,每行M个小数,表示表格中对应的Pij。
输入以N=M=0结束,这组数据不输出结果。
Output
对于每组数据,输出对应游戏总得分的数学期望的最大值,四舍五入精确至4位小数。每组数据的输出占一行。
Sample Input
2 3
1.0 1.0 1.0
0.5 0.4 0.3
0 0
Sample Output
1.0600

主要思想是,将二维数组每一列排序,然后依次选取每一列的当前最大值为一组。
这样就是期望最大,大概是数学知识吧。
难点就在如何排序每一列。
便将二维数组先横置。再排序每一行,可以用sort因为他们是相邻的。
注意sort时 里面的参数需要是一位数组,就取二维数组的行元素。

#include<iostream>
#include<algorithm>
using namespace std;
unsigned long long int am, bm;
int main() {
    int x, y;
    float A[105][14] ;
    float B[14][105];
    while (scanf_s("%d%d", &x, &y)&&(x!=0||y!=0)) {
        for (int i = 0; i < x; i++) {
            for (int m = 0; m < y; m++) {
                double c;
                cin >> c;
                A[i][m] = c;
                B[m][i] = c;
            }
        }
        for (int m = 0; m < y; m++) {
            sort(B[m], B[m] + x);
        }
        double sum = 0;
        for (int i = 0; i < x; i++) {
            double ans = 1;
            for(int m=0;m<y;m++)
                ans *= B[m][i];
            sum += ans;
        }
        printf("%.4lf\n", sum);
    }
}

猜你喜欢

转载自blog.csdn.net/sc_jn/article/details/80247332
今日推荐