标签:des style blog io os for sp div on
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)
标签:des style blog io os for sp div on
原文地址:http://www.cnblogs.com/haohaooo/p/4014647.html