#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; }