結果

問題 No.309 シャイな人たち (1)
ユーザー parukiparuki
提出日時 2016-06-28 11:12:28
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 809 ms / 4,000 ms
コード長 2,499 bytes
コンパイル時間 1,627 ms
コンパイル使用メモリ 171,484 KB
実行使用メモリ 20,480 KB
最終ジャッジ日時 2024-04-20 04:33:13
合計ジャッジ時間 12,174 ms
ジャッジサーバーID
(参考情報)
judge3 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 792 ms
20,480 KB
testcase_01 AC 783 ms
20,368 KB
testcase_02 AC 802 ms
20,308 KB
testcase_03 AC 761 ms
20,300 KB
testcase_04 AC 17 ms
20,160 KB
testcase_05 AC 188 ms
20,216 KB
testcase_06 AC 790 ms
20,320 KB
testcase_07 AC 771 ms
20,444 KB
testcase_08 AC 759 ms
20,352 KB
testcase_09 AC 780 ms
20,368 KB
testcase_10 AC 776 ms
20,336 KB
testcase_11 AC 768 ms
20,352 KB
testcase_12 AC 809 ms
20,480 KB
testcase_13 AC 5 ms
20,096 KB
testcase_14 AC 6 ms
20,096 KB
testcase_15 AC 192 ms
20,320 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include "bits/stdc++.h"
using namespace std;
#define FOR(i,j,k) for(int (i)=(j);(i)<(int)(k);++(i))
#define rep(i,j) FOR(i,0,j)
#define each(x,y) for(auto &(x):(y))
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define debug(x) cout<<#x<<": "<<(x)<<endl
#define smax(x,y) (x)=max((x),(y))
#define smin(x,y) (x)=min((x),(y))
#define MEM(x,y) memset((x),(y),sizeof (x))
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<ll> vll;

int bitcnt(int n){
    int res = 0;
    while(n){
        if(n&1) ++res;
        n>>=1;
    }
    return res;
}

const double EPS = 1e-14;
int R, C;
double P[11][11], prob[12][1 << 11];
int S[11][11], nextHands[1 << 22], dontKnow[1 << 11];

void solve(){
    rep(mask, 1 << C)
        rep(i, C)
            if((mask >> i & 1) == 0)
                dontKnow[mask] |= (3 << (2 * i));

    rep(mask, 1 << (C * 2)){
        queue<int> Q;
        vi state(C);
        rep(x, C){
            state[x] = mask >> (2 * x) & 3;
            if(state[x] == 0)Q.push(x + 1), Q.push(x - 1);
        }
        while(sz(Q)){
            int x = Q.front(); Q.pop();
            if(x < 0 || x >= C || state[x] <= 0)continue;
            if(--state[x] == 0)Q.push(x - 1), Q.push(x + 1);
        }
        rep(x, C)if(state[x] <= 0)nextHands[mask] |= 1 << x;
    }

    double ans = 0.0;
    prob[0][0] = 1;
    rep(y, R){
        vector<double> rowProb(1 << C, 1.0);
        rep(mask, 1 << C)rep(x, C){
            if(mask >> x & 1)rowProb[mask] *= P[y][x];
            else rowProb[mask] *= 1 - P[y][x];
        }
        rep(upMask, 1 << C){
            int needMask = 0;
            rep(x, C){
                int need = 4 - (upMask >> x & 1) - (4 - S[y][x]);
                smin(need, 3);
                smax(need, 0);
                needMask |= need << (x * 2);
            }
            rep(knowMask, 1 << C){
                int nextUpMask = nextHands[needMask | dontKnow[knowMask]];
                prob[y + 1][nextUpMask] += prob[y][upMask] * rowProb[knowMask];
            }
        }
        rep(mask, 1 << C)ans += bitcnt(mask)*prob[y + 1][mask];
    }
    printf("%0.20f\n", ans);
}

int main(){
    
    while(cin >> R >> C){
        rep(i, R)rep(j, C){
            cin >> P[i][j];
            P[i][j] *= 0.01;
        }
        rep(i, R)rep(j, C)cin >> S[i][j];
        rep(i, R + 1)rep(j, 1 << C)prob[i][j] = 0;
        MEM(nextHands, 0);
        MEM(dontKnow, 0);
        solve();
    }
}
0