hdu5378
关于逆元的相关知识已经总结到这里:求i模p的逆元中
还有关于这道题,在测试样例时,一直是错误的,最后才发现是求快速幂即ni函数时,其中的x没有设为long long int,谨记,虽然x乘完自己后或模上1000000007,但是还没模之前可能超过int的范围,但不会超过long long int的范围,所以要把x设为long long int。
不过关于这道题,嗯,用概率来求方法数,谁也限制不住人类的大脑啊!!!(今天学校停水,早晨没吃到牛肉馅的包子,中午懒在机房,所以吃了一天的面包,咸菜,不说了,说多了都是泪!!!我要吃肉!!!)
2015.8.29:
今天再次看着道题,一开始偷瞄到一点是通过概率求总共有多少种方法,但是死活也记不起到底该怎么求,依稀的记忆+推理得出是二维的dp,然后就死活就认准了dp[i][j]代表以i为根节点的子树中有j个minister,然后就只能朝着背包的方向去想了,最后感觉这样能做,但是不如原先的方法简单,虽然记不起原先的方法是什么了。然后打开题解,结果发现竟然看不懂了,在网上找题解,从新整理这道题,最后总算发现,不是智商问题,还算欣慰
。
题解中dp[i][j]代表1到i中有几个点在以它为根节点的子树中是最大的,那么相当于是前i个点中选择了j个让它成为以它为根节点的子树中最大的,并没有其它的含义了,不要再多想了,如果可以的话,想要冲着刚才的自己这样喊,然后递归就行了。
下面证明为什么在1到i中有j个是以它为根节点的子树中最大的,那么就只有j个minister:
首先,可以得知,这j个点必定是minister;
其次,假如说存在第j+1个minister,那么存在某个包括这个点的子树中这个点最大,任何一棵子树如果包括这个点的话,那么就肯定包括以这个点为根节点的那棵子树,所以在以这个点为根节点的子树中这个点也是最大的,与前面的假设,相违背,所以不可能存在第j+1个minister。
最后,没有最后。
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 1010
#define MOD 1000000007
long long int dp[N][N];
int siz[N];
int head[N],to[2*N],nextedge[2*N];
int cou;
long long int A[N];
void add(int a,int b){
to[cou]=b;nextedge[cou]=head[a];head[a]=cou++;
}
void dfs(int u,int fa){
siz[u]=1;
for(int i=head[u];i!=-1;i=nextedge[i]){
int v=to[i];
if(v==fa){
continue;
}
else{
dfs(v,u);
siz[u]+=siz[v];
}
}
return;
}
long long int ni(long long int x){
int y=MOD-2 ;
long long int ans=1;
while(y){
if(y%2){
ans=ans*x%MOD;
}
y=y/2;
x=x*x%MOD;
}
return ans;
}
int main(){
int t;
int n;
int k;
int a,b;
A[0]=1;
for(int i=1;i<N;i++){
A[i]=A[i-1]*i%MOD;
}
scanf("%d",&t);
for(int cas=1;cas<=t;cas++){
scanf("%d%d",&n,&k);
memset(head,-1,sizeof(head));
cou=0;
for(int i=1;i<n;i++){
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
dfs(1,-1);
memset(dp,0,sizeof(dp));
dp[1][1]=ni(siz[1]);
dp[1][0]=(siz[1]-1)*dp[1][1]%MOD;
for(int i=2;i<=n;i++){
long long int tempg=ni(siz[i]);
dp[i][0]=dp[i-1][0]*(siz[i]-1)%MOD*tempg%MOD;
for(int j=1;j<=i;j++){
dp[i][j]=(dp[i-1][j]*(siz[i]-1)%MOD*tempg%MOD+dp[i-1][j-1]*tempg%MOD)%MOD;
}
}
printf("Case #%d: %d\n",cas,(A[n]*dp[n][k]%MOD));
}
return 0;
}

浙公网安备 33010602011771号