CodeForces - 16E(狀壓dp)
阿新 • • 發佈:2020-10-09
const int maxn = 5e4 + 10; double dp[1 << 18]; int num[1 << 18]; double pic[20][20]; int sta[20][maxn], cnt[20]; int lowbit(int x) { return (x & (-x)); } int main() { int n; scanf("%d", &n); for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) scanf("%lf", &pic[i][j]); int limit = (1 << n); for (int i = 1; i < limit; ++i) num[i] = num[i - lowbit(i)] + 1; for (int i = 0; i < limit; ++i) {//預處理出不同種1個數的狀態 int temp = num[i]; sta[temp][cnt[temp] ++] = i; } dp[limit - 1] = 1; for (int i = n-1; i >= 1; --i) {//剩餘的魚條數 for (int j = 0; j < cnt[i]; ++j) { int now = sta[i][j];//當前狀態 for (int k = 0; k < n; ++ k) {//添個1 int pre = (now | (1 << k)); if (pre == now) continue; int c = (i * (i + 1)) / 2;//C(i+1, 2), 即兩條魚中間偶遇的可能 for(int z = 0; z < n; ++ z) if((1 << z) & pre) dp[now] += dp[pre] * pic[z][k] / c; } } } for (int i = 1; i < limit; i <<= 1) printf("%.6lf%c", dp[i], i == limit - 1 ? '\n' : ' '); return 0; }