#P1191. 排列
排列
Description
给定一个长度为 NN 的排列,但是排列中某些位置的值被擦去了。
你想要还原这个排列,但是你唯一记得的信息是这个排列的逆序对个数为 KK.
你想知道,有多少不同的还原方式,使得排列的逆序对数为 KK.
一个排列的逆序对个数即满足 i < ji<j, p_i > p_jpi>pj的(i,j)(i,j) 个数。
Input Format
第一行两个正整数 N,KN,K.
接下来一行 NN 个整数 p_1,p_2,...p_Np1,p2,...pN, 如果 p_i=0pi=0 则表示这个位置的值被擦去了。
保证至少存在一个排列满足给定的格式。
Output Format
一行一个整数,表示答案。
4 3
0 0 4 0
2
Hint
N,K < 15#include <stdio.h>
int N, K, p[17], vis[17], ans;
inline int count() {
int i, j, result = 0;
for(i = 1; i < N; i++)
for(j = i+1; j <= N; j++)
if(p[i] > p[j]) result++;
return result;
}
void search(int depth) {
if(depth == N+1) {
ans = count() == K ? ans+1 : ans;
return;
}
int i;
if(p[depth]) search(depth+1);
else {
for(i = 1; i <= N; i++)
if(!vis[i] && !p[depth]) {
vis[i] = 1;
p[depth] = i;
search(depth+1);
vis[i] = p[depth] = 0;
}
}
}
int main() {
int i, cnt = 0;
scanf("%d %d", &N, &K);
for(i = 1; i <= N; i++)
scanf("%d", &p[i]);
for(i = 1; i <= N; i++) {
if(p[i]) vis[p[i]] = 1;
else cnt++;
}
search(1);
printf("%d\n", ans);
return 0;
}