这是一份wa on test 2的代码
/*
口台 口台
令人咍咍。
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 35, M = 350, mod = 1e9 + 7;
int n, c[M][M], f[N][M], cnt[N];
void Add(int &x, int y){
x = (x + y) % mod;
}
int main() {
// freopen("ex.in", "r", stdin);
// freopen("ex.out", "w", stdout);
n = 26;
for(int i = 1; i <= n; i++) scanf("%d", &cnt[i]);
c[0][0] = 1;
for(int i = 1; i <= 300; i++){
c[i][0] = 1;
for(int j = 1; j <= i; j++)
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;//,cout<<i<<" "<<j<<" "<<c[i][j]<<endl;
}
int sum = cnt[1];
f[1][cnt[1] - 1] = 1;
for(int i = 2; i <= n; i++){
for(int j = 0; j < sum; j++){
if(cnt[i] == 0){
f[i][j] = f[i - 1][j];
} else{
for(int k = 0; k <= j && k <= cnt[i]; k++)//k个去疏通j个不合法的
for(int l = max(k, 1); l <= cnt[i] && l <= sum + 1; l++)//将cnt[i]分成l块
Add(f[i][j - k + cnt[i] - l],
1ll * f[i - 1][j] * c[cnt[i] - 1][l - 1] % mod
* c[j][k] % mod * c[sum + 1 - j][l - k] % mod);
}
}
sum += cnt[i];
}
printf("%d\n", f[n][0]);
return 0;
}
这是一份AC代码
/*
口台 口台
令人咍咍。
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 35, M = 350, mod = 1e9 + 7;
int n, c[M][M], f[N][M], cnt[N];
void Add(int &x, int y){
x = (x + y) % mod;
}
int main() {
//freopen("ex.in", "r", stdin);
//freopen("ex.out", "w", stdout);
for(int i = 1; i <= 26; i++){
scanf("%d", &cnt[i]);
if(cnt[i]) cnt[++n] = cnt[i];
}
c[0][0] = 1;
for(int i = 1; i <= 300; i++){
c[i][0] = 1;
for(int j = 1; j <= i; j++)
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;//,cout<<i<<" "<<j<<" "<<c[i][j]<<endl;
}
int sum = cnt[1];
f[1][cnt[1] - 1] = 1;
for(int i = 2; i <= n; i++){
for(int j = 0; j < sum; j++)
for(int k = 0; k <= j && k <= cnt[i]; k++)//k个去疏通j个不合法的
for(int l = max(k, 1); l <= cnt[i] && l <= sum + 1; l++)//将cnt[i]分成l块
Add(f[i][j - k + cnt[i] - l],
1ll * f[i - 1][j] * c[cnt[i] - 1][l - 1] % mod
* c[j][k] % mod * c[sum + 1 - j][l - k] % mod);
sum += cnt[i];
}
printf("%d\n", f[n][0]);
return 0;
}
注意到他们唯一的区别就是一个一开始就判掉,另一个在dp的时候复制上一个。
感觉非常离谱,第一份代码为什么会出错?