您的位置:首页 > 大数据 > 人工智能

Codeforces Round #317 [AimFund Thanks-Round] (Div. 2) C(组合数+容斥)

2015-08-24 14:44 495 查看
题目地址:Lengthening Sticks

题意:给出a,b,c,L,要求a+x,b+y,c+z构成三角形,x+y+z<=L,问有多少中分法(x,y,z可为0)。

思路:用容斥来搞,结果ans=全部组合的情况-不符合三角形定理的情况。

1.求全部组合的情况:

当L=0时,res=1;

当L=1时,res=3;所以当L=1时形成的情况为1+3=4

当L=2时,res=6;所以当L=2时形成的情况为4+6=10

当L=3时,res=10; 所以当L=3时形成的情况为10+10=20

……..

所以由上面可以推出当L=n时,全部的组合情况是C(n+3,3)。

2.不符合三角形定理的情况:

如果要形成一个三角形,那么必须任意两边之和大于第三边。那么不符合的就是任意一边大于等于其余两边的和。所以分别把a,b,c当成第三边,然后再考虑将剩下的l拆分三份分配给a,b,c依旧不满足的情况即可。

我们先把a当成第三边,然后给a增加一个La,现在i=a+La,Max=a+b+c+L。现在我们考虑b+c的范围,因为是不满足的情况,所以b+c的变化范围<=i,又因为总长度Max的限制,b+c<=Max-i,所以b+c的最大变化范围只能在min(i,Max-i)。令x=min(i,Max-i)-b-c表示总共变化量的大小,即Lb+Lc<=x,等价于tmp+Lb+Lc的方案数。

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const double pi= acos(-1.0);
const double esp=1e-6;
using namespace std;
const int Maxn=1e5+10;
LL Ex(LL a,LL b,LL c,LL L)
{
LL res=0;
LL Max=a+b+c+L;
for(LL i=a;i<=L+a;i++){
if(b+c>i) continue;
else{
LL x=min(i,Max-i)-b-c;
res+=(x+2)*(x+1)/2;
}
}
return res;
}
int main()
{
LL a,b,c,L;
LL ans;
while(~scanf("%lld %lld %lld %lld",&a,&b,&c,&L)){
ans=(L+3)*(L+2)*(L+1)/6;
//printf("%lld\n",ans);
ans-=Ex(a,b,c,L);
//printf("%lld\n")
ans-=Ex(b,a,c,L);
ans-=Ex(c,a,b,L);
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: