【USACO08NOV】奶牛混合起来Mixed Up Cows
题目描述
约翰有 N 头奶牛,第 i 头奶牛的编号是 S i ,每头奶牛的编号都不同。这些奶牛最近在闹脾气,
为表达不满的情绪,她们在排队的时候一定要排成混乱的队伍。如果一只队伍里所有位置相邻的奶牛
的编号之差都大于 K,那么这就是一只混乱的队伍,其中 K 是一个给定的整数。比如说,当 K = 2
时,序列 (1,3,5,2,6,4) 就是一支混乱的队伍,而 (1,3,6,5,2,4) 不是,因为 6 和 5 只差 1,不够混
乱。请问,这 N 头奶牛可以排成多少种混乱的队形呢?
输入
• 第一行:两个整数 N 和 K,4 ≤ N ≤ 16, 1 ≤ K ≤ 3400
• 第二行到第 N + 1 行:第 i + 1 行有一个整数 S i ,1 ≤ S i ≤ 25000
输出
• 单个整数:表示混乱队伍的数量
样例输入
4 1 3 4 2 1
样例输出
2
提示
两种排法是 3,1,4,2 和 2,4,1,3
题解:
乱搞搞对的,不知对不对,看到n<=16 于是想到状压
F[i][j] 表示以i结尾,状态为j的方案数
然后就是如果满足 S[i]-S[k]>p 就F[i][j]+=F[k][j-(1<<(i-1))]
注意开long long
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=17; 7 int a[N];long long F[N][1<<N]; 8 int main() 9 { 10 int n,p; 11 scanf("%d%d",&n,&p); 12 for(int i=1;i<=n;i++)scanf("%d",&a[i]),F[i][(1<<(i-1))]=1; 13 sort(a+1,a+n+1); 14 int m=(1<<n)-1; 15 for(int j=1;j<=m;j++) 16 { 17 for(int i=1;i<=n;i++) 18 { 19 if(!(j&(1<<(i-1))))continue; 20 for(int k=1;k<=n;k++) 21 { 22 if(abs(a[i]-a[k])<=p)continue; 23 if(!(j&(1<<(k-1))))continue; 24 F[i][j]+=F[k][j-(1<<(i-1))]; 25 } 26 } 27 } 28 long long ans=0; 29 for(int i=1;i<=n;i++)ans+=F[i][m]; 30 printf("%lld",ans); 31 return 0; 32 }