1. 程式人生 > 其它 >洛谷 P2915 [USACO08NOV]Mixed Up Cows G

洛谷 P2915 [USACO08NOV]Mixed Up Cows G

Description

P2915 [USACO08NOV]Mixed Up Cows G

Solution

狀壓\(dp\)

首先設計狀態:\(f[i][j]\) 表示以 \(i\) 結尾的狀態為 \(j\) 且符合條件的排列共有多少種。

最終的 \(ans = {\sum_{i = 1} ^ {n} f[i][(1<<n) - 1]}\)

再來看轉移方程。

當狀態\(j\) 中不包含 \(k\),且狀態 \(j\) 中包含 \(i\),那麼:

\(f[i][j | (1 << (k - 1))] += f[k][j]\)

然後就沒別的啦,下面程式碼中 \(i\)\(j\)

是反過來的。

注意要開 \(long \ long\)

Code

#include <bits/stdc++.h>
#define ll long long

using namespace std;

const ll N = 20;
ll n, m;
ll f[N][1 << 17], a[N];

signed main(){
    scanf("%d%d", &n, &m);
    for(ll i = 1; i <= n; i++){
        scanf("%d", &a[i]);
        f[i][1 << (i - 1)] = 1;
    }
    for(ll i = 0; i < (1 << n); i++)
        for(ll j = 1; j <= n; j++)
            for(ll k = 1; k <= n; k++){
                if(!(i & (1 << (j - 1))) && (i | (1 << (k - 1))) == i && abs(a[j] - a[k]) > m)
                    f[j][i | (1 << (j - 1))] += f[k][i];
            }
    ll ans = 0;
    for(ll i = 1; i <= n; i++)
        ans += f[i][(1 << n) - 1];
    printf("%lld\n", ans);
    return 0;
}

End

本文來自部落格園,作者:{xixike},轉載請註明原文連結:https://www.cnblogs.com/xixike/p/15163572.html