博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
uva 11401思维+预处理
阅读量:6202 次
发布时间:2019-06-21

本文共 1559 字,大约阅读时间需要 5 分钟。

1.题意描述

给定边长为1,2,3,····n的n条边,现在要在里面任意选取三条边构成三角形,我们需要求一共可以构成多少个三角形?

2.题目分析

首先我们分析数据大小问题,由于数据最大可以达到10^6。所以我们如果直接枚举时间复杂度可以达到O(n^3),那么我们可以肯定的说这个时间复杂度肯定是不能承受的。

那么我们可以根据前面求整理的排列组合公式的求二项式系数的方法联想到使用递推法。这样时间复杂度可以降低到O(n)。这是可以承受的。要想用递推法,我们肯定需要使用打表的方法----预处理,那么空间复杂度肯定是O(n)同样可以承受。现在我们分析怎样使用递推法:

我们先定义一个函数f(n):当最大编程为n时所能构成的三角形数目。

对于三角形的三边而言,我们可以设定为x,y,z。并且我们假设x是最大边。那么我们有y+z>x,因此可以推出x-y<z<x。

根据这个不等式我们有,当y=1时,显然无解;当y=2时,有一个解;当y=3时,有两个解;·····当y=x-1时有x-2个解。根据等差数列求和公式我们有一共有

0+1+2+······+(x-2)=(x-1)(x-2)/2。但是我们需要注意,这里包含了y=z情况。那么我们需要减去从y=x/2+1开始到y=x-1为止,此时我们多计数了(x-1)-(x/2+1)+1=(x-1)/2个解,而且除此之外,我们对于每一个y我们都有重复计数,因为前后是对称的。所以我们最后还要除以2得到最终结果。

最终结果为:

          

那么最后的递推式我们可以写为:

          

到这里基本分析完毕。

wa的第一点  数组超了,后面还存了10000005

wa的第二点  数据爆了,不要强制转换,直接定义i为longlong 

1 #include
2 #include
3 #include
4 using namespace std; 5 long long f[1000001];//wa的第一点 数组超了,后面还存了10000005 6 int main() 7 { 8 //先打表预处理 9 f[3]=0;10 for(int i=4;i<=1000005;i++)11 f[i]=f[i-1]+(long long)(((i-1)*(i-2)/2-(i-1)/2)/2);// wa的第二点 数据爆了,不要强制转换,直接定义i为longlong 12 int n;13 while(~scanf("%d",&n))14 {15 if(n<3)16 break;17 cout<
<

ac代码:

#include
#include
#include
using namespace std;long long f[1000010];int main(){ //先预处理 f[3]=0; for(long long i=4;i<=1000005;i++) f[i]=f[i-1]+((i-1)*(i-2)/2-(i-1)/2)/2; int n; while(~scanf("%d",&n)) { if(n<3) break; cout<
<

  

转载于:https://www.cnblogs.com/Aiahtwo/p/10921530.html

你可能感兴趣的文章
用Vim搭建C/C++开发环境
查看>>
关于box-shadow和drop-shadow的显著区别
查看>>
POJ 刷题进程.2
查看>>
安装php xdebug扩展
查看>>
[PHP] 算法-二叉树的子结构判断的PHP实现
查看>>
python re.sub
查看>>
Spring Cache 配置及一些问题的解决
查看>>
ASP.NET MVC 3 网站优化总结(六)压缩 HTML
查看>>
透彻理解块级元素的宽度
查看>>
把图片存入数据库
查看>>
冒泡排序
查看>>
HttpClient和HttpURLConnection的区别
查看>>
BZOJ-1024: [SCOI2009]生日快乐 (搜索经典好题)
查看>>
第六章函数与宏定义
查看>>
在 .NET Core 中结合 HttpClientFactory 使用 Polly(上篇)
查看>>
【369】列表/字典的分拆, unpacking
查看>>
Effect_Players
查看>>
制作百度地图
查看>>
CSS文档流
查看>>
win7下内核调试
查看>>