题目描述:有二十个色子,每个点数为1-12,求有多少种方法使得最大的10个点数和为70
twenty = 12 ???
F[i,j,k] 第 i 大的数为 j,且前 i 大的数的和为 k 的方案数
然后是一个组合数问题QAQ
注意第 i 大和 i+1 大相等
【答案】7448717393364181966
#include <iostream>
#include <cstdio>
#include <algorithm>
#define LL long long
#define rep(i,s,t) for (int i = s;i <= t;i ++)
using namespace std;
LL f[11][13][75],C[21][21],ans;
int main()
{
rep(i,0,20)
{
C[i][0] = 1;
rep(j,1,i) C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
}
f[0][13][0] = 1;
rep(i,1,10) rep(j,1,12) rep(k,1,70)
rep(ii,0,i-1) if (k >= (i-ii) * j) rep(jj,j+1,13)
f[i][j][k] += f[ii][jj][k - (i - ii) * j] * C[20 - ii][i - ii];
rep(i,0,9) rep(j,2,13) rep(k,0,69) rep(jj,1,j-1)
if (70 - k == (10 - i) * jj)
{
LL sum = 0,t = 1;
rep(n,0,9) sum += C[20 - i][n] * t,t *= jj - 1;
ans += f[i][j][k] * sum;
}
rep(j,2,12)
{
LL t = 1;
rep(n,1,10) t *= j - 1;
ans += f[10][j][70] * t;
}
cout << ans << endl;
}