1. 程式人生 > >【狀壓DP】奶牛混合起來Mixed Up Cows

【狀壓DP】奶牛混合起來Mixed Up Cows

題目

思路

我們設 f[i][j]表示以第i只奶牛為結尾的狀態為j的隊伍混亂的方案數是多少

我們知道對於每一個狀態都有很多結尾,於是我們用兩個迴圈,一個列舉狀態,一個列舉結尾的奶牛

當然我們還需要判斷這個情況是否存在,比如說f[2][10]吧,它表示10這個狀態也就是1010,以第二隻奶牛為結尾的方案數,這種情況顯然是不存在的,因為在1010這個狀態中第二隻奶牛根本沒有被選擇,根本不可能成為結尾,所以對於這種情況我們需要進行判斷

在最後我們統計答案的時候要把列舉各種奶牛作為結尾且所有奶牛均被選擇的情況

程式碼

#include<iostream>
#include<cstdio>
#include<cstring>
int abs(int x)
{
    return x>0?x:-x;
}
const int N=1<<18;
long long f[18][N];
int num[18];
int main()
{
    memset(f,0,sizeof(f));
    int n,K;
    scanf("%d%d",&n,&K);
    for(int i=1; i<=n; i++) scanf("%d",&num[i]);
    for(int i=1; i<=n; i++) f[i][1<<(i-1)]=1;
    for(int i=1; i<(1<<n); i++)
        for(int j=1; j<=n; j++)
            for(int k=1; k<=n; k++)
                if(abs(num[j]-num[k])>K&&((1<<(j-1))&i)&&(((1<<(k-1))&i)==0))
                    f[k][((1<<(k-1))|i)]+=f[j][i];
    long long sum=0;
    for(int i=1; i<=n; i++) sum+=f[i][(1<<n)-1];
    printf("%lld\n",sum);
    return 0;
}