我不知道为什么我会在第10个案件中获得WA, 我使用了BIT和组合。 问题链接:SPOJ INCSEQ
问题细节:给定N(1≤N≤10,000)个整数S1,...,SN(0≤Si<100,000)的序列,计算长度为K(1≤K)的S的增加子序列的数量≤50且K≤N);也就是说,K元组i1,...,iK的数量使得1≤i1<1。 ......&lt; iK≤N且Si1 < ......&lt;植
这是My Code
我认为使用Mod功能的nCr存在问题。 他们没有给出失败的测试用例,所以我没有任何失败的测试用例。
// Here i compute nCk
unsigned long long combination(ll n,ll k)
{
unsigned long long ans=1;
k=k>n-k?n-k:k;
ll j=1;
for(; j<=k; j++,n--)
{
if(n%j==0)
{
ans*=n/j;
}
else if(ans%j==0)
{
ans=ans/j*n;
}
else
{
ans=(ans*n)/j;
}
}
return ans%mod;
}
plz help
答案 0 :(得分:1)
您的combination
方法错误,因为对于大数字,nCr的结果将大于long long
范围。
因此,有效地使用模数,我们可以避免在这种情况下溢出
我们知道还有另一种计算nCr的方法
我们知道
nCr = (n - 1)C(r - 1) + (n - 1)Cr
由于k <= 50这个很小,我们可以按如下方式计算我们的组合表c
:
int[][]c = new int[n + 1][k+1];
c[0][0] = 1;
for (int i = 1; i <= n; i++) {
c[i][0] = 1;
if(i <= k)
c[i][i] = 1;
for (int j = 1; j <= k; j++) {
c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
c[i][j] %= mod;
}
}
mod操作将确保我们的结果永远不会溢出。