結果
問題 | No.309 シャイな人たち (1) |
ユーザー | Min_25 |
提出日時 | 2015-12-02 13:51:39 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 153 ms / 4,000 ms |
コード長 | 3,404 bytes |
コンパイル時間 | 587 ms |
コンパイル使用メモリ | 67,688 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-09-14 07:52:01 |
合計ジャッジ時間 | 2,380 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 101 ms
6,812 KB |
testcase_01 | AC | 113 ms
6,940 KB |
testcase_02 | AC | 21 ms
6,940 KB |
testcase_03 | AC | 100 ms
6,944 KB |
testcase_04 | AC | 5 ms
6,940 KB |
testcase_05 | AC | 26 ms
6,944 KB |
testcase_06 | AC | 14 ms
6,940 KB |
testcase_07 | AC | 31 ms
6,944 KB |
testcase_08 | AC | 108 ms
6,940 KB |
testcase_09 | AC | 119 ms
6,940 KB |
testcase_10 | AC | 150 ms
6,944 KB |
testcase_11 | AC | 153 ms
6,940 KB |
testcase_12 | AC | 134 ms
6,940 KB |
testcase_13 | AC | 2 ms
6,944 KB |
testcase_14 | AC | 2 ms
6,944 KB |
testcase_15 | AC | 4 ms
6,940 KB |
コンパイルメッセージ
main.cpp: In function ‘int main()’: main.cpp:86:18: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 86 | int R, C; scanf("%d %d", &R, &C); | ~~~~~^~~~~~~~~~~~~~~~~ main.cpp:88:28: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 88 | rep(i, R) rep(j, C) scanf("%d", &r), P[i][j] = r / 100.; | ~~~~~^~~~~~~~~~ main.cpp:89:28: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 89 | rep(i, R) rep(j, C) scanf("%d", &S[i][j]), S[i][j] = 4 - S[i][j]; | ~~~~~^~~~~~~~~~~~~~~~
ソースコード
#include <cstdio> #include <cassert> #include <algorithm> #include <iostream> #include <vector> #include <queue> #include <utility> using namespace std; using uint64 = unsigned long long; #define rep(i, n) for (int i = 0; i < int(n); ++i) constexpr int ipow(int base, int e, int res = 1) { return e == 0 ? res : (e & 1) ? ipow(base * base, e / 2, res * base) : ipow(base * base, e / 2, res); } using Pair = pair<double, double>; Pair operator + (const Pair& lhs, const Pair& rhs) { return Pair(lhs.first + rhs.first, lhs.second + rhs.second); } // precision ... Pair operator - (const Pair& lhs, const Pair& rhs) { return Pair(lhs.first - rhs.first, lhs.second - rhs.second); } Pair& operator += (Pair& lhs, const Pair& rhs) { return lhs = lhs + rhs; } constexpr int N = 11; constexpr int three_N = ipow(3, N); double P[N][N]; int S[N][N]; Pair dp[2][1 << N]; Pair cumu[three_N]; int offsets[1 << N]; template <typename T> void arith_transform_plus(T* A, int lvn) { int n = 1 << lvn; reverse(A, A + n); for (int lvm = lvn; lvm > 0; --lvm) { int m = 1 << lvm; int mh = m >> 1; for (int r = 0; r < n; r += m) rep(j, mh) A[r + j] += A[r + mh + j]; } } template <typename T> void sum(T* A, int lv, T* res) { int total = 1 << lv; int pos = 0; rep (i, total) { res[pos++] = A[i]; int f = i; int t = 1; while (f) { int r = f & -f; int ofs = offsets[i ^ r]; rep(j, t) res[pos + j] = res[ofs + j] - res[pos - t + j]; pos += t; t <<= 1; f ^= r; } } } int ctz(int n) { return __builtin_ctz(n); } int pop_count(int n) { return __builtin_popcount(n); } int main() { int R, C; scanf("%d %d", &R, &C); int r; rep(i, R) rep(j, C) scanf("%d", &r), P[i][j] = r / 100.; rep(i, R) rep(j, C) scanf("%d", &S[i][j]), S[i][j] = 4 - S[i][j]; int total = 1 << C; int ofs = 0; rep(i, total) offsets[i] = ofs, ofs += 1 << pop_count(i); auto* curr = dp[0], *next = dp[1]; fill(curr, curr + total, Pair(0, 0)); curr[0] = Pair(0., 1.); arith_transform_plus(curr, C); sum(curr, C, cumu); rep(y, R) { fill(next, next + total, Pair(0, 0)); rep(s2, total) { double p = 1.0; rep(x, C) p *= (s2 & (1 << x)) ? P[y][x] : 1. - P[y][x]; if (p == 0) continue; auto s1 = s2; int ofs = offsets[s1] + (1 << pop_count(s2)) - 1; int points_back[N] = {}; int points[N]; rep(x, C) if (s2 & (1 << x)) points_back[x] = S[y][x]; do { if (cumu[ofs].second) { copy(points_back, points_back + C, points); auto s = s1; while (s) { auto t = s & -s; points[ctz(t)] += 1; s ^= t; } for (int x = 0; x < C - 1; ++x) if (points[x] >= 4) points[x + 1] += 1; for (int x = C - 1; x > 0; --x) if (points[x] >= 4) points[x - 1] += 1; int nstate = 0; rep(x, C) if (points[x] >= 4) { nstate |= 1 << x; } next[nstate] += Pair(p * (cumu[ofs].first + pop_count(nstate) * cumu[ofs].second), p * cumu[ofs].second); } s1 = (s1 - 1) & s2; ofs -= 1; } while (s1 != s2); } swap(curr, next); arith_transform_plus(curr, C); sum(curr, C, cumu); } printf("%.12f\n", cumu[0].first); return 0; }