結果

問題 No.309 シャイな人たち (1)
ユーザー Min_25Min_25
提出日時 2015-12-02 01:37:50
言語 C++11
(gcc 11.4.0)
結果
TLE  
実行時間 -
コード長 2,744 bytes
コンパイル時間 496 ms
コンパイル使用メモリ 63,644 KB
実行使用メモリ 40,928 KB
最終ジャッジ日時 2023-10-12 08:46:51
合計ジャッジ時間 30,358 ms
ジャッジサーバーID
(参考情報)
judge11 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2,695 ms
40,928 KB
testcase_01 TLE -
testcase_02 AC 676 ms
36,472 KB
testcase_03 AC 3,431 ms
36,520 KB
testcase_04 AC 29 ms
4,348 KB
testcase_05 AC 581 ms
13,824 KB
testcase_06 AC 657 ms
36,604 KB
testcase_07 AC 744 ms
36,712 KB
testcase_08 AC 3,569 ms
36,472 KB
testcase_09 TLE -
testcase_10 TLE -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

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

typedef unsigned uint;
using namespace std;

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

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

double ps[2048];
double pts[2048][11];

uint trans[1 << 22][2];

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;

  for (uint s = 0; s < total * total; ++s) {
    uint points[11] = {0};
    uint plus[11] = {0};

    for (uint x = 0; x < C; ++x) {
      points[x] = ((s >> (2 * x)) & 3) + 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;
      }
    }
    trans[s][0] = nstate;
    trans[s][1] = cnt;
  }

  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 s2 = 0; s2 < total; ++s2) {
      double p = 1.0;
      for (uint x = 0; x < C; ++x) {
        if (s2 & (1 << x)) {
          p *= P[y][x];
          pts[s2][x] = 4 - S[y][x];
        } else {
          p *= 1 - P[y][x];
          pts[s2][x] = 0;
        }
      }
      ps[s2] = p;
    }

    for (uint s1 = 0; s1 < total; ++s1) {
      if (pcurr[s1] == 0) {
        continue;
      }

      for (uint s2 = 0; s2 < total; ++s2) {
        double p = ps[s2];
        if (p == 0) {
          continue;
        }

        uint s = 0;
        for (uint x = 0; x < C; ++x) {
          int p = pts[s2][x];
          if (s1 & (1 << x)) {
            p += 1;
          }
          uint t = min(3, max(0, int(p - 1)));
          s |= t << (x * 2);
        }

        uint nstate = trans[s][0];
        uint cnt = trans[s][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