Codeforces 571A 容斥
2015-08-23 13:53
246 查看
Codeforces 571A
题目链接:
http://codeforces.com/problemset/problem/57
题意:
给三根棍子,长度分别为a,b,c。现有长度L,可使三根棍子的长度任意增加且增加总和小于等于L。问有多少种增加方案。
思路:
感谢http://blog.csdn.net/stl112514/article/details/47904301
容斥,即用增加综总和小于等于L的方案总数减去不合法数。总数C(L+3,3),这是一个合成公式。具体是C(2,2)+C(3,2)+C(4,2)+...+C(L,2)。这个公式又是怎么得出来的,假设当前棍子长度增加综合为i,则有C(i+2,2)种选择方案(有i+2个空可以选,而选择是有序的,因为第一根棍子选择的切点必须在第二个前面,但是可以同时选一个空)。
不合法数。枚举以哪一条边作为最大第三边(设为a),先把它加成最大第三边,用去长度i(i>=0)。然后枚举它长度是a+i, a+i+1,....a+L的情况。此时假设当前用去长度i,则最大可用剩余长度是min( L - i, a + i - b - c),这个应该不需要解释。然后在这些长度里面任意分配,用到之前C(i+2,2)的公式。
这里可能不合法数计算会有出现重复情况的疑惑。刚刚写了一大版全删了。。。最大边都不一样怎么会重,对于一个确定最大边的情况,函数里面枚举的是另外两条边分配剩余长度且仍旧不合法的方案数。
源码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
#define LL long long
#define gmax(a,b) ((a) > (b) ? (a) : (b))
#define gmin(a,b) ((a) < (b) ? (a) : (b))
LL cal(LL a, LL b, LL c, LL l)
{
// printf("a = %I64d, b = %I64d, c = %I64d\n", a, b, c);
LL ans = 0;
for(int i = gmax(0, b + c - a) ; i <= l ; i++){
int x = gmin(l - i , a + i - b - c);
ans += (LL)(x + 1) * (x + 2) / 2;
}
// printf("ans = %I64d\n", ans);
return ans;
}
int main()
{
LL a, b, c, l;
while(scanf("%I64d%I64d%I64d%I64d", &a, &b, &c, &l) != EOF){
LL ans = (LL)(l + 3) * (l + 2) / 2 * (l + 1) / 3;
ans -= cal(a, b, c, l);
ans -= cal(b, c, a, l);
ans -= cal(c, a, b, l);
printf("%I64d\n", ans);
}
return 0;
}
题目链接:
http://codeforces.com/problemset/problem/57
题意:
给三根棍子,长度分别为a,b,c。现有长度L,可使三根棍子的长度任意增加且增加总和小于等于L。问有多少种增加方案。
思路:
感谢http://blog.csdn.net/stl112514/article/details/47904301
容斥,即用增加综总和小于等于L的方案总数减去不合法数。总数C(L+3,3),这是一个合成公式。具体是C(2,2)+C(3,2)+C(4,2)+...+C(L,2)。这个公式又是怎么得出来的,假设当前棍子长度增加综合为i,则有C(i+2,2)种选择方案(有i+2个空可以选,而选择是有序的,因为第一根棍子选择的切点必须在第二个前面,但是可以同时选一个空)。
不合法数。枚举以哪一条边作为最大第三边(设为a),先把它加成最大第三边,用去长度i(i>=0)。然后枚举它长度是a+i, a+i+1,....a+L的情况。此时假设当前用去长度i,则最大可用剩余长度是min( L - i, a + i - b - c),这个应该不需要解释。然后在这些长度里面任意分配,用到之前C(i+2,2)的公式。
这里可能不合法数计算会有出现重复情况的疑惑。刚刚写了一大版全删了。。。最大边都不一样怎么会重,对于一个确定最大边的情况,函数里面枚举的是另外两条边分配剩余长度且仍旧不合法的方案数。
源码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
#define LL long long
#define gmax(a,b) ((a) > (b) ? (a) : (b))
#define gmin(a,b) ((a) < (b) ? (a) : (b))
LL cal(LL a, LL b, LL c, LL l)
{
// printf("a = %I64d, b = %I64d, c = %I64d\n", a, b, c);
LL ans = 0;
for(int i = gmax(0, b + c - a) ; i <= l ; i++){
int x = gmin(l - i , a + i - b - c);
ans += (LL)(x + 1) * (x + 2) / 2;
}
// printf("ans = %I64d\n", ans);
return ans;
}
int main()
{
LL a, b, c, l;
while(scanf("%I64d%I64d%I64d%I64d", &a, &b, &c, &l) != EOF){
LL ans = (LL)(l + 3) * (l + 2) / 2 * (l + 1) / 3;
ans -= cal(a, b, c, l);
ans -= cal(b, c, a, l);
ans -= cal(c, a, b, l);
printf("%I64d\n", ans);
}
return 0;
}
相关文章推荐
- 编写高质量代码改善C#程序的157个建议——建议127:用形容词组给接口命名
- 斜率大法题库
- POJ 1064 && HDU 1551 Cable master(二分)
- hdu 1176 免费馅饼
- IOS开发中设置控件内容对齐方式时容易混淆的几个属性
- Python抓取网页数据 生成 iOS plist 文件
- Java 操作集合的工具类:Collections
- 第三节:springmvc+hibernate+spring整合实例
- server启动故障处理 com.ibm.ws.exception.RuntimeError
- UIButton
- Struts2学习(五)访问web元素总结
- POJ 1050 && HDU 1081 To the Max(前缀和)
- python中两个整数相除得到浮点数的方法
- spark core源码分析1 集群启动及任务提交过程
- hdu 1231 最大连续子序列
- servlet第2讲(下集)----创建servlet实例(继承GenericServlet)
- python连接,操作pgsql
- sql server 调优要点
- POJ 1046 Color Me Less(水~)
- maven中 Could not create local repository问题原因及解决方法