这题刘汝佳大白书上的例题,自己总结一番,寻找递推关系。
题意是从1~n中选择3个数,一共可以组成多少个三角形。
1.组成三角形的条件是x+y>z,假设三角形最大的边是x则有x-y<z<x, y=1,z有0个值, y=2, z有1个值, y=3, z有两个值。。。y=x-1, z有x-2个值,等差数列的和为(x-1)*(x-2)/2。
2.除去重复计算的值,因为y和z可以互换所以每个三角形被统计了两次,题目要求选出三个不同的整数,因此必须除去z=y的情况。
如果y=z则有,x/2+1~x-1共有x-1-(x/2+1)+1=x/2-1个数。因此总数是((x-1)*(x-2)/2-[x/2-1])/2。
所以对于一个x c(x)=((x-1)*(x-2)/2-[x/2-1])/2. f(x)表示包含最大边为x的三角形的个数。
所以递推式是f(x)=f(x-1)+c(x).
#include<iostream>
#include<fstream>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
const double eps(1e-8);
typedef long long lint;
#define clr(x) memset( x , 0 , sizeof(x) )
#define repf(i, a, b) for (int i = (a); i <= (b); ++i)
#define repd(i, a, b) for (int i = (a); i >= (b); --i)
#define clrs( x , y ) memset( x , y , sizeof(x) )
#define MAXN 1000010
lint f[MAXN];
void init()
{
clr(f);
for(lint i=3;i<=MAXN-10;i++)
{
f[i]=f[i-1]+((i-1)*(i-2)/2-(i/2-1))/2;
}
}
int main()
{
int n;
init();
while(scanf("%d",&n)==1)
{
if(n<3)break;
cout<<f[n]<<endl;
}
}