您的位置:首页 > 其它

codeforces Helvetic Coding Contest 2016 D2 The Wall (medium)

2016-07-11 17:28 288 查看

题目链接:

http://codeforces.com/contest/690/problem/D2

题目大意:

一共有n块砖,筑成一道宽度为不超过c的墙,有多少的建筑方案?(n块不必要都用)

结题思路:

枚举用的砖数,用的砖数为i时的建筑方案数为(i+c−1i)。

这有一个定理把n个相同的物品放入m个不同的盒子中(盒子可为空)的情况数(n+m−1m−1)。这个公式可这样理解有n+m−1个物品,把其中m−1个变成分割线,原来的n个物品被分成m部分。

所以原题就变成∑n1(i+c−1i),求组合数用卢卡斯定理,这题就解决了。

另外还有o(1)的解法,ans=(max(n,c)min(n,c))−1,至于为什么还不知道。

#include<cstdio>
#include<cstdlib>
#define LL long long
const int mod=1000003;
LL f[700010];  //N为组合数的底数 的范围
void init(int p){
f[0] = 1;
for(int i = 1; i <= 700000; ++i)
f[i]  = f[i-1] * i % p;
}
LL pow_mod(LL a, LL x, int p){
LL ret = 1;
a %= p;
while(x){
if(x & 1){
ret = ret * a % p;
--x;
}
else{
a = a * a % p;
x >>= 1;
}
}
return ret;
}
LL Lucas(LL n, LL k, int p){
LL ret = 1;
while(n && k){
LL nn = n % p, kk = k % p;
if(nn < kk) return 0;
ret = ret * f[nn] * pow_mod(f[kk] * f[nn - kk] % p, p - 2, p) % p;
n /= p;
k /= p;
}
return ret;
}
int main(){
int n,c;
LL ans=0;
init(mod);
scanf("%d%d",&n,&c);
for(int i=1;i<=n;++i){
ans=(ans+Lucas(i+c-1,i,mod))%mod;
}
printf("%I64d\n",ans);
//system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: