ickchen2

zoj 3404 Sticker

问一个n长度的数有多少种可以利用某些转换转换成只有1到N的数。可以把能用A换B的变成从A连向B的一条边
由于题目说明每个点的出度和入度不大于1。因此图中只有两种情况,一个是链,一个是环。链的话,如果长度是M,就表示从长度为k的未放置格中取出m个位置来放置这m个数。而因此链上的点可以向下转换,因此可以用DP来解决dp[i,j]表示第i个点占用了j个位置的方案数dp[i,j]=sum(dp[i-1][k]*c[j][k])。环也一样,不过链要求I各点最多只能放I个位置,不然链头的某些点就不能从某些点得到了。环就无此限制
最后扫描一下图,统计一下就行了

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<string>
  4 #include<vector>
  5 #include<map>
  6 #include<queue>
  7 #include<algorithm>
  8 #define M 1000
  9 #define clr(x) memset(x,0,sizeof(x))
 10 #define _clr(x) memset(x,-1,sizeof(x))
 11 #define fr(i,a,b) for(int i=a;i<b;++i)
 12 #define pf printf
 13 #define sf scanf
 14 #define pb push_back
 15 #define mp make_pair
 16 #define ll long long
 17 #define debug 1
 18 using namespace std;
 19 const ll mod=(ll)1000000007;
 20 ll dp1[201][201],dp2[201];
 21 ll c[201][201];
 22 ll pow(int a,int b)
 23 {
 24     ll ret=1;
 25     while(b>0)
 26     {
 27         if(b&1){ret=(ret*a)%mod;}
 28         a=((ll)a*a)%mod;
 29         b>>=1;
 30     }
 31     return ret;
 32 }
 33 void init()
 34 {
 35     clr(c);
 36     c[0][0]=1;
 37     fr(i,1,201)
 38     {
 39         c[i][0]=1;
 40         fr(j,1,i+1)
 41         {
 42             c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
 43         }
 44     }
 45     clr(dp1);
 46     dp1[0][0]=1;
 47     //链DP
 48     fr(i,1,201)
 49     {
 50 
 51         fr(j,0,i+1)
 52         {
 53             //链上第i个节点用了j个位置
 54             fr(k,0,j+1)
 55                 dp1[i][j]=(dp1[i][j]+dp1[i-1][k]*c[j][j-k])%mod;
 56         }
 57     }
 58     //
 59     fr(i,1,201)
 60     {
 61         dp2[i]=pow(i,i);
 62     }
 63 }
 64 int to[201];
 65 int v[201];
 66 int s[201];
 67 vector<int>h,l;
 68 vector< pair<int,int> >ft;
 69 int main()
 70 {
 71     freopen("in.txt","r",stdin);
 72     init();
 73     int T;
 74     sf("%d",&T);
 75     while(T--)
 76     {
 77         int n,m;
 78         sf("%d%d",&n,&m);
 79         _clr(to);
 80         clr(v);
 81         _clr(s);
 82         fr(i,0,m)
 83         {
 84             int a,b;
 85             sf("%d%d",&a,&b);
 86             to[a]=b;
 87             s[b]=a;
 88         }
 89         int pos=n;
 90         ll ans=1;
 91         fr(i,0,n)
 92         {
 93             if(v[i])continue;
 94             int now=i;
 95             int count=0;
 96             while(now!=-1&&!v[now])
 97             {
 98                 v[now]=1;
 99                 ++count;
100                 //if(to[now]==-1)break;
101                 now=to[now];
102             }
103             if(now!=-1)
104             {
105                // pf("cc=%d\n",count);
106                 ans=(ans*c[pos][count])%mod;
107                 ans=(ans*dp2[count])%mod;
108                 pos-=count;
109             }
110             else
111             {
112                 now=s[i];
113                 while(now!=-1)
114                 {
115                     //pf("now=%d\n",now);
116                     v[now]=1;
117                     now=s[now];
118                     ++count;
119                 }
120                 //pf("c=%d\n",count);
121                 ans=(ans*c[pos][count])%mod;
122                 ans=(ans*dp1[count][count])%mod;
123                 pos-=count;
124             }
125         }
126         pf("%lld\n",ans);
127     }
128     return 0;
129 }
130 

posted on 2010-09-07 22:14 神之子 阅读(394) 评论(5)  编辑 收藏 引用 所属分类: zoj月赛

评论

# re: zoj 3404 Sticker 2010-10-02 20:51 am

题目还是不太懂啊。
n=5,m=3
0-1
1-2
3-4
为什么答案是480????好像是450啊  回复  更多评论   

# re: zoj 3404 Sticker 2010-10-03 13:54 ickchen2

0-1
就是0 0可以转成0 1,1 0,1 1
也可以转成0 2,2 0,2 1,1 2,2 2
是不是算少了?  回复  更多评论   

# re: zoj 3404 Sticker 2010-10-03 14:01 神之子

0-1
就是0 0可以转成0 1,1 0,1 1
也可以转成0 2,2 0,2 1,1 2,2 2
是不是算少了?  回复  更多评论   

# re: zoj 3404 Sticker 2010-11-07 21:26 am

还是不太懂诶。。。
题目的意思是不是一个长度为n的排列。有多少种排列可以通过转换得到一个n的全排列。而且每种转换最多只能使用一次。
像n=5 m=3
0-1
1-2
3-4
那么原来可以是00234(C(5,2)*A(3,3)种) 、 00134 ······ 或者不使用任何一种交换A(5,5)种;然后把所有情况加起来。
还是我理解错了?????@神之子
  回复  更多评论   

# re: zoj 3404 Sticker 2010-11-08 09:25 ickchen2

@am
没错
但不一定是只用一种,可以用两种以上  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

常用链接

留言簿(1)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜