首页 > 代码库 > HDU 5399 Too Simple(过程中略微用了一下dfs)——多校练习9
HDU 5399 Too Simple(过程中略微用了一下dfs)——多校练习9
Too Simple
Teacher Mai has
She wants to know how many different function series
The following are
If there is only one number
3 3 1 2 3 -1 3 2 1
1HintThe order in the function series is determined. What she can do is to assign the values to the unknown functions.
题意:给你m个函数f1,f2,?,fm:{1,2,?,n}→{1,2,?,n}(即全部的x∈{1,2,?,n},相应的f(x)∈{1,2,?,n})。已知当中一部分函数的函数值,问你有多少种不同的组合使得全部的i(1≤i≤n),满足f1(f2(?fm(i)))=i
对于函数集f1,f2,?,fm and g1,g2,?,gm。当且仅当存在一个i(1≤i≤m),j(1≤j≤n),fi(j)≠gi(j),这种组合才视为不同。
假设还是不理解的话,我们来解释一下例子,3 3
1 2 3
-1
3 2 1
例子写成函数的形式就是
n=3,m=3
f1(1)=1,f1(2)=2,f1(3)=3
f2(1)、f2(2)、f2(3)的值均未知
f3(1)=3,f3(2)=2,f3(3)=1
所以要使全部的i(1≤i≤n),满足f1(f2(?fm(i)))=i。仅仅有一种组合情况,即f2(1)=3,f2(2)=2,f2(3)=1这么一种情况
解题思路:事实上。细致想想。你就会发现,此题的解跟-1的个数有关,当仅仅有一个-1的时候,由于相应关系都已经决定了。所以仅仅有1种可行解,而当你有两个-1时,当中一个函数的值能够依据还有一个函数的改变而确定下来,故有n!种解。
依此类推,当有k个-1时,解为
所以,我们仅仅须要提前将n!
计算好取模存下来。剩下的就是套公式了
有一点须要提醒的是,当-1的个数为0时。即不存在-1的情况,解并不一定为0,若不存在-1的情况下仍满足对于全部的i(1≤i≤n),满足f1(f2(?fm(i)))=i,输出1。否则输出0。所以加个dfs推断一下方案是否可行。多校的时候就被这一点坑了。看来还是考虑得不够多。
若对上述有什么不理解的地方,欢迎提出。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<math.h> #include<vector> #include<map> #include<set> #include<stdlib.h> #include<cmath> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 105; const int inf = 1000000000; const int mod = 1000000007; __int64 s[N]; bool v[N]; int w[N][N]; int dfs(int t,int x) { if(t==1) return w[t][x]; return dfs(t-1,w[t][x]); } int main() { int n,m,i,j,k,x; bool flag; __int64 ans; s[0]=1; for(i=1;i<N;i++) s[i]=(s[i-1]*i)%mod; while(~scanf("%d%d",&n,&m)) { flag=true; for(k=0,i=1;i<=m;i++) { scanf("%d",&x); if(x==-1) k++; else { memset(v,false,sizeof(v)); v[x]=true;w[i][1]=x; for(j=2;j<=n;j++) { scanf("%d",&x); v[x]=true; w[i][j]=x; } for(j=1;j<=n;j++) if(!v[j]) break; if(j<=n) flag=false; } } /*for(i=1;i<=m;i++) { for(j=1;j<=n;j++) printf("%d ",w[i][j]); printf("\n"); }*/ if(!flag) puts("0"); else if(!k) { for(i=1;i<=n;i++) if(dfs(m,i)!=i) break; //printf("%d*\n",i); if(i>n) puts("1"); else puts("0"); } else { for(ans=1,i=1;i<k;i++) ans=ans*s[n]%mod; printf("%I64d\n",ans); } } return 0; }菜鸟成长记
HDU 5399 Too Simple(过程中略微用了一下dfs)——多校练习9