描述:
Each of Farmer John's N (4 <= N <= 16) cows has a unique serial number S_i (1 <= S_i <= 25,000). The cows are so proud of it that each one now wears her number in a gangsta manner engraved in large letters on a gold plate hung around her ample bovine neck.
Gangsta cows are rebellious and line up to be milked in an order called 'Mixed Up'. A cow order is 'Mixed Up' if the sequence of serial numbers formed by their milking line is such that the serial numbers of every pair of consecutive cows in line differs by more than K (1 <= K <= 3400). For example, if N = 6 and K = 1 then 1,3, 5, 2, 6, 4 is a 'Mixed Up' lineup but 1, 3, 6, 5, 2, 4 is not (since the consecutive numbers 5 and 6 differ by 1).
How many different ways can N cows be Mixed Up?
输入:
* Line 1: Two space-separated integers: N and K
* Lines 2..N+1: Line i+1 contains a single integer that is the serial
number of cow i: S_i
输出:
* Line 1: A single integer that is the number of ways that N cows can
be 'Mixed Up'. The answer is guaranteed to fit in a 64 bit
integer.
样例输入:
4 1
3
4
2
Each of Farmer John's N (4 <= N <= 16) cows has a unique serial number S_i (1 <= S_i <= 25,000). The cows are so proud of it that each one now wears her number in a gangsta manner engraved in large letters on a gold plate hung around her ample bovine neck.
Gangsta cows are rebellious and line up to be milked in an order called 'Mixed Up'. A cow order is 'Mixed Up' if the sequence of serial numbers formed by their milking line is such that the serial numbers of every pair of consecutive cows in line differs by more than K (1 <= K <= 3400). For example, if N = 6 and K = 1 then 1,3, 5, 2, 6, 4 is a 'Mixed Up' lineup but 1, 3, 6, 5, 2, 4 is not (since the consecutive numbers 5 and 6 differ by 1).
How many different ways can N cows be Mixed Up?
输入:
* Line 1: Two space-separated integers: N and K
* Lines 2..N+1: Line i+1 contains a single integer that is the serial
number of cow i: S_i
输出:
* Line 1: A single integer that is the number of ways that N cows can
be 'Mixed Up'. The answer is guaranteed to fit in a 64 bit
integer.
样例输入:
4 1
3
4
2
1
2
题意:
给出n个数,组成一个每两个数之间相差必须大于m的排列;
求这样的排列有多少个;
题解:
n<=16的范围,很可能是状压或搜索之类的算法;
考虑组成这样子的排列,下一个数是什么仅由其上一个的大小决定;
那么就可以设状态为f[i][j],其中i是目前排列的结尾数的序号;
j为表示n个数中取了哪些的状态(因为j里面已经包括了个数所以就不需要再列出来个数了);
判断两个数是否相邻我用了邻接矩阵。。;
然后转移好像有点麻烦,写成dfs感觉好写多了;
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 20
using namespace std;
typedef long long ll;
int n,m,a[N],can[N][65555];
ll f[N][65555];
bool map[N][N];
ll dfs(int d,int now,int pre)
{
if(f[pre][now])
{
return f[pre][now];
}
if(d==n)
{
return 1;
}
int i;
ll ret=0;
for(i=1;i<=n;i++)
{
if(map[pre][i]&&(now&(1<<i))==0)
ret+=(f[i][now|(1<<i)]=dfs(d+1,now|(1<<i),i));
}
return ret;
}
int main()
{
int i,j,k;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",a+i);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(abs(a[i]-a[j])>m)
map[i][j]=1;
for(i=0;i<=n;i++)
map[0][i]=1,map[i][0]=1;
printf("%lld",dfs(0,0,0));
}