結果

問題 No.309 シャイな人たち (1)
ユーザー Min_25Min_25
提出日時 2015-12-02 00:57:18
言語 C++11
(gcc 11.4.0)
結果
TLE  
実行時間 -
コード長 2,204 bytes
コンパイル時間 492 ms
コンパイル使用メモリ 61,816 KB
実行使用メモリ 11,972 KB
最終ジャッジ日時 2023-10-12 08:28:41
合計ジャッジ時間 10,986 ms
ジャッジサーバーID
(参考情報)
judge13 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 TLE -
testcase_01 -- -
testcase_02 -- -
testcase_03 -- -
testcase_04 -- -
testcase_05 -- -
testcase_06 -- -
testcase_07 -- -
testcase_08 -- -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <cstdio>
#include <iostream>
#include <vector>

typedef unsigned uint;
using namespace std;

double P[11][11];
uint S[11][11];

double dp[2][2048];
double pdp[2][2048];

int main() {
  uint R, C; scanf("%u %u", &R, &C);

  for (uint i = 0; i < R; ++i) {
    for (uint j = 0; j < C; ++j) {
      uint r; scanf("%u", &r);
      P[i][j] = double(r) / 100;
    }
  }

  for (uint i = 0; i < R; ++i) {
    for (uint j = 0; j < C; ++j) {
      scanf("%u", &S[i][j]);
    }
  }

  uint total = 1 << C;

  double* curr = dp[0], *next = dp[1];
  double* pcurr = pdp[0], *pnext = pdp[1];
  fill(curr, curr + total, .0);
  fill(pcurr, pcurr + total, .0);

  pcurr[0] = 1.0;
  for (uint y = 0; y < R; ++y) {
    fill(next, next + total, 0);
    fill(pnext, pnext + total, 0);
    for (uint s1 = 0; s1 < total; ++s1) {
      if (pcurr[s1] == 0) {
        continue;
      }
      for (uint s2 = 0; s2 < total; ++s2) {
        uint points[11] = {0};
        uint plus[11] = {0};
        double p = 1.0;
        for (uint x = 0; x < C; ++x) {
          if (s2 & (1 << x)) {
            p *= P[y][x];
            points[x] = 4 - S[y][x];
          } else {
            p *= 1 - P[y][x];
            points[x] = 0;
          }
          if (s1 & (1 << x)) {
            points[x] += 1;
          }
        }
        bool updated = true;
        while (updated) {
          updated = false;
          for (int x = 0; x < C; ++x) {
            uint pl = 0;
            if (x - 1 >= 0 && points[x - 1] >= 4) pl += 1;
            if (x + 1 < C  && points[x + 1] >= 4) pl += 1;
            if (pl > plus[x]) {
              points[x] += pl - plus[x];
              plus[x] = pl;
              updated = true;
            }
          }
        }
        uint nstate = 0;
        uint cnt = 0;
        for (uint x = 0; x < C; ++x) {
          if (points[x] >= 4) {
            nstate |= 1 << x;
            cnt += 1;
          }
        }
        next[nstate] += (curr[s1] + cnt * pcurr[s1]) * p;
        pnext[nstate] += pcurr[s1] * p;
      }
    }
    swap(curr, next);
    swap(pcurr, pnext);
  }
  double ans = 0;
  for (uint i = 0; i < total; ++i) {
    ans += curr[i];
  }
  printf("%.12f\n", ans);
  return 0;
}
0