题干:
Country Far-Far-Away is a big country with N cities. But it is now under a civil war. The rebel uses the ancient tunnel network which connects all N cities with N-1 inter-city tunnels for transportation. The government army want to destroy these tunnels one by one. After several months fighting, some tunnels have been destoryed. According to the intel, the tunnel network have excatly S connected components now. And what government army further knows is that city 1, 2, ... , S belong to each of the S connected components. Since the government have little knowledge about the remaining tunnels, they ask you to calculate the number of possible networks of remaining tunnels.
Input
There are multiple test cases. The first line of input contains an integer T (T ≤ 500) indicating the number of test cases. Then T test cases follow.
Each case contains one line containing two integer N (2 ≤ N ≤ 2000) and S (2 ≤ S≤ N), as described above.
Output
The number of possible networks now. Since the number might be very large, you should output the answer after modulo 1000000007.
Sample Input
4 3 2 4 2 5 3 100 50
Sample Output
2 8 15 113366355
解题报告:
且不说会不会T的问题,这个思路应该是没错的,但是只能过小样例,过不了大样例,不知道为什么。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int main() {
int T;
scanf("%d",&T);
while(T--) {
ll n,s;
scanf("%lld %lld",&n,&s);
ll ans=s;
for(ll i=1; i<n-s; i++) {
ans=(ans*n)%mod;
}
if(n==s)ans=1;
printf("%lld\n",ans);
}
return 0;
}
WA代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;
const ll mod = 1000000007;
int n,s;
ll C[2005][2005];
ll dp[2005][2005];
ll qpow(ll a,ll k) {
if(k<=0) return 1;
ll res = 1;
while(k) {
if(k&1) res = (res * a) % mod;
a=(a*a)%mod;
k>>=1;
}
return res;
}
void init() {
C[0][0] = 1;
for(int i = 1; i<=2002; i++) {
C[i][0] = 1;
for(int j = 1; j<=2002; j++) {
C[i][j] = C[i-1][j] + C[i-1][j-1];
}
}
}
int main()
{
init();
int t;
cin>>t;
// dp[i][j]代表前i个集合中放入了j个点的方案数。
while(t--) {
scanf("%d%d",&n,&s);
memset(dp,0,sizeof dp);
dp[0][0]=1;
for(int i = 0; i<=n-s; i++) {
dp[1][i] = (C[n-s][i]*qpow(i+1,i-1))%mod;
}
for(int i = 2; i<=s; i++) {
for(int j = 0; j<=n-s; j++) {
for(int k = 0; k<=j; k++) {
dp[i][j] = (dp[i][j] + C[n-s-(j-k)][k] * dp[i-1][j-k]*qpow(k+1,k-1))%mod;
}
}
}
ll ans = dp[s][n-s];
// for(int i = 1; i<=n-s; i++) {
// ans = (ans + dp[s][i])%mod;
// }
printf("%lld\n",ans);
}
return 0 ;
}
/*
100
4 1
*/