版权声明:转载者乖乖♂站好 https://blog.csdn.net/Eric1561759334/article/details/82931051
题目
https://www.luogu.org/problemnew/show/P2915
思路
我们设 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;
}