Triangle Counting UVA - 11401 数三角形 递推

题目链接

有多少种方法可以从1. 2.3. .... n 中选出3 个不同的整数,使得以它们为主边长可以组成三角形?比如n=5 时有3 种方法,即(2 ,3 ,4) , (2,3,5), (3人5) 0 n=8 时有22 种方法。
【输入格式】
输入包含多组测试数据,每组数据的第一行为整数n (3!::三n 运1000000) 。输入用n<3 的标志结束。
【输出格式】
对于每组数据,输出其方案总数。
【分析】
三重循环的时间复杂度为O(n亏,采用这种方法肯定超时。这样的规模即使是O(n2) 时间的算法都很难承受,那么只能进行-些数学分析了。
用加法原理,设最大边长为x 的三角形有c(x)个,另外两条边长分别为y 和z , 根据三角形不等式①有y+z>x 。所以z 的范围是x-y<z<x。
根据这个不等式,当户1 时.x- l<z勺,显然无解:y=2 时只有一个解(z=.x- l) ;y=3 时有两个解(z=x-l 或者z=x-2) …… 直到y=x-l 时有x-2 个解。根据等差数列求和公式, 一共有0+1 +2+... +(.x-3)+(x-2)=(x-l)(x-2)/2 个解。
可惜,这并不是c(x)的正确数值,因为上面的解包含了严茸的情况,而且每个三角形算了两遍(想一想,为什么〉。解决方案很简单,首先统计y=z 的情况。y 的取值从x/2+1 开始到x-l 为止, 一共有x-1 -x/2=(.x- l )/2 个解,然后把这部分解扣除,再除以2 ,即

                                                    
原题要求的实际上是"最大边长不超过n 的三角形数目" 贝的。根据加法原理,f(n)=c( 1 )+c(2)+. . . +c( n) 。可以写成递推式f(n) = f(n-1)+c(n) 。代码如下。

#include <iostream>
using namespace std;
const int N = 1000000;
long long f[N+5]; // int存不下
int main(int argc, char** argv) {	
	f[3] = 0;
	for(long long x = 4; x <= N; x++)
		f[x] = f[x-1] + ((x-1)*(x-2)/2 - (x-1)/2)/2;
	int n;
	while( cin>> n && n >= 3)
		cout<< f[n] << "\n";
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值