Given a permutation of n: a[0], a[1] ... a[n-1], ( its elements range from 0 to n-1, For example: n=4, one of the permutation is 2310) we define the swap operation as: choose two number i, j ( 0 <= i < j <= n-1 ), take a[i] out and then insert a[i] to the back of a[j] of the initial permutation to get a new permutation :a[0], a[1], ..., a[i-1], a[i+1], a[i+2] ... a[j-1], a[j], a[i], a[j+1], ..., a[n-1]. For example: let n = 5 and the permutation be 03142, if we do the swap operation be choosing i = 1, j = 3, then we get a new permutation 01432, and if choosing i = 0, j = 4, we get 31420.
Given a confusion matrix of size n*n which only contains 0 and 1 (ie. each element of the matrix is either 0 or 1), the confusion value of a permutation a[0],a[1], ..., a[n-1] can be calculated by the following function:
int confusion() { int result = 0; for(int i = 0;i < n-1; i++) for(int j = i+1; j < n; j++) { result = result + mat[a[i]][a[j]]; } return result; }
Besides, the confusion matrix satisfies mat[i][i] is 0 ( 0 <= i < n) and mat[i][j] + mat[j][i] = 1 ( 0 <= i < n, 0 <= j < n, i != j ) given the n, the confusion matrix mat, you task is to find out how many permutations of n satisfies: no matter how you do the swap function on the permutation(only do the swap function once), its confusion value does not increase.
The first line is the number of cases T(1 <= T <= 5), then each case begins with a integer n (2 <= n <= 12), and the next n line forms the description of the confusion matrix (see the sample input).
For each case , if there is no permutation which satisfies the condition, just print one line “-1”, or else, print two lines, the first line is a integer indicating the number of the permutations satisfy the condition, next line is the Lexicographic smallest permutation which satisfies the condition.
2 2 0 1 0 0 3 0 0 0 1 0 1 1 0 0
1 0 1 1 1 2 0
题解:DFS
从后向前搜索,放进去的一位要和后面的每一段(n~n-1,n~n-2...n~0)保持1的个数大于0的个数,如果成立,则这一位可以放这个数,在向前继续搜索。
因为只能前面的数插入到后面,所以不需要考虑新加进去的数会不会对后面已经排好的短造成影响。也是这个原因要从后向前搜索。
AC代码:
#include<iostream> #include<cstdio> #include<cstring> #define M(a,b) memset(a,b,sizeof(a)) using namespace std; int ans[25]; int num[25][25]; int out[25]; int n; int ct; void print() { //cout<<‘?‘<<endl; int flag = 1; for(int i = n-1;i>=0;i--) { if(ans[i]<out[i]) {flag = 0; break;} if(ans[i]>out[i]) break; } if(!flag) for(int i = n-1;i>=0;i--) out[i] = ans[i]; ct++; } void dfs(int pos) { if(pos>=n) { print(); return; } if(pos == 0) { for(int i = 0;i<n;i++) { ans[pos] = i; dfs(pos+1); } } else { for(int i = 0;i<n;i++) { int cnt = 0; int flag = 1; for(int j = pos-1;j>=0;j--) { if(num[i][ans[j]]==0) {flag = 0;break;} cnt += num[i][ans[j]]; //cout<<i<<‘ ‘<<ans[j]<<‘ ‘<<num[i][ans[j]]<<‘ ‘<<cnt<<endl; if(cnt<0) {flag = 0;break;} } if(flag) {ans[pos] = i; dfs(pos+1);} } } return; } int main() { int t; scanf("%d",&t); while(t--) { ct = 0; scanf("%d",&n); M(num,0); M(ans,0); M(out,0x3f); for(int i = 0;i<n;i++) for(int j = 0;j<n;j++) { scanf("%d",&num[i][j]); if(i == j) num[i][j] = 0; else if(num[i][j]==0) num[i][j] = -1; } dfs(0); if(ct==0) {puts("-1"); continue;} printf("%d\n",ct); for(int j = n-1;j>0;j--) printf("%d ",out[j]); printf("%d\n",out[0]); } return 0; }
soj4271 Love Me, Love My Permutation (DFS)
原文:http://www.cnblogs.com/haohaooo/p/4014647.html