BZOJ1231: [Usaco2008 Nov]mixup2 混乱的奶牛
1231: [Usaco2008 Nov]mixup2 混乱的奶牛
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 587 Solved: 323
[Submit][Status]
Description
混乱的奶牛 [Don Piele, 2007] Farmer John的N(4 <= N <= 16)头奶牛中的每一头都有一个唯一的编号S_i (1 <= S_i <= 25,000). 奶牛为她们的编号感到骄傲, 所以每一头奶牛都把她的编号刻在一个金牌上, 并且把金牌挂在她们宽大的脖子上. 奶牛们对在挤奶的时候被排成一支"混乱"的队伍非常反感. 如果一个队伍里任意两头相邻的奶牛的编号相差超过K (1 <= K <= 3400), 它就被称为是混乱的. 比如说,当N = 6, K = 1时, 1, 3, 5, 2, 6, 4 就是一支"混乱"的队伍, 但是 1, 3, 6, 5, 2, 4 不是(因为5和6只相差1). 那么, 有多少种能够使奶牛排成"混乱"的队伍的方案呢?
Input
* 第 1 行: 用空格隔开的两个整数N和K
* 第 2..N+1 行: 第i+1行包含了一个用来表示第i头奶牛的编号的整数: S_i
Output
第 1 行: 只有一个整数, 表示有多少种能够使奶牛排成"混乱"的队伍的方案. 答案保证是 一个在64位范围内的整数.
Sample Input
4 1
3
4
2
1
3
4
2
1
Sample Output
2
输出解释:
两种方法分别是:
3 1 4 2
2 4 1 3
输出解释:
两种方法分别是:
3 1 4 2
2 4 1 3
HINT
Source
题解:
竟然1A了。。。
状压DP,f[i][j]表示选的牛的集合为i,最后一个是j,使得队列混乱的排列数目。
代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 1000000000 13 #define maxn 100000 14 #define maxm 500+100 15 #define eps 1e-10 16 #define ll long long 17 #define pa pair<int,int> 18 using namespace std; 19 inline int read() 20 { 21 int x=0,f=1;char ch=getchar(); 22 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 23 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 24 return x*f; 25 } 26 ll f[maxn][20]; 27 int a[20],b[20][maxn],n,m; 28 int main() 29 { 30 freopen("input.txt","r",stdin); 31 freopen("output.txt","w",stdout); 32 n=read();m=read(); 33 for(int i=1;i<=n;i++)a[i]=read(); 34 for(int i=0;i<=((1<<n)-1);i++) 35 { 36 int x,y; 37 for(x=i,y=0;x;x-=x&(-x))y++; 38 b[y][++b[y][0]]=i; 39 } 40 memset(f,0,sizeof(f)); 41 for(int i=1;i<=n;i++)f[b[1][i]][i]=1; 42 for(int i=2;i<=n;i++) 43 for(int j=1;j<=b[i][0];j++) 44 { 45 int x=b[i][j]; 46 for(int k=1;k<=n;k++) 47 if(x&(1<<(k-1))) 48 for(int l=1;l<=n;l++) 49 if(l!=k&&(x&((1<<l-1)))&&abs(a[k]-a[l])>m) 50 f[x][k]+=f[x^(1<<(k-1))][l]; 51 } 52 ll ans=0; 53 for(int i=1;i<=n;i++)ans+=f[(1<<n)-1][i]; 54 printf("%lld\n",ans); 55 return 0; 56 }