E - Internal Rate of Return

题目:here

题目大意:给出CF[0]<0,CF[i]>0,i>0,求IRR(IRR>-1)令NPV = 0.

思路:设f(IRR) = NPV,这就变成了一个函数,稍微观察一下,可以发现当IRR∈(-1, +∞)的时候是单调递减的(好像是吧做完忘了),这样我们就可以二分答案0点了。当IRR无限接近-1的时候,f(IRR)→+∞(好像是吧),当 IRR→+∞时,f(IRR)→CF[0]<0,令left = -1、right = 1e5(我也不知道该取什么我随便取的然后AC了),随便二分一下就好。

PS:恩?说完了?那什么时候输出No和Too many啊?关于这个坑爹的问题,看完前面的分析,笔者完全不知道什么时候会出现这两个答案,于是妥妥地没将这两个东西写进代码然后AC了。这里还有一个 小技巧,题目的样例完全没有出现No和Too many这两种答案,很可能说明这两种答案都是不存在的。比如很多的题目说如果什么什么得不到答案就输出-1那样,它的样例大多都会有一个是输出-1的, 当然这不是绝对的……

复制代码
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cmath>
 6 using namespace std;
 7 
 8 const int MAXN = 13;
 9 const double EPS = 1e-4;
10 
11 inline int sgn(double x) {
12     if(fabs(x) < EPS) return 0;
13     return x > 0 ? 1 : -1;
14 }
15 
16 int CF[MAXN];
17 int T;
18 
19 double f(double IRR) {
20     double ret = CF[0], tmp = 1 + IRR;
21     for(int i = 1; i <= T; ++i) {
22         ret += CF[i] / tmp;
23         tmp = tmp * (1 + IRR);
24     }
25     return ret;
26 }
27 
28 double solve() {
29     double ans = -2;
30     double L = -1, R = 1e5;
31     while(R - L > EPS) {
32         double mid = (R + L) / 2;
33         if(sgn(f(mid)) == 1) L = mid;
34         else R = mid;
35     }
36     return ans = L;
37 }
38 
39 int main() {
40     while(scanf("%d", &T) != EOF) {
41         if(T == 0) break;
42         for(int i = 0; i <= T; ++i) scanf("%d", &CF[i]);
43         //double t; while(cin>>t) cout<<f(t)<<endl;
44         printf("%.2f\n", solve());
45     }
46 }
复制代码

 

posted on   SCNUACM  阅读(206)  评论(0)    收藏  举报

编辑推荐:
· 字符集、编码的前世今生
· Web性能优化:从 2 秒到200毫秒
· WPF 使用GDI+提取图片主色调并生成Mica材质特效背景
· golang遍历处理map时的常见性能陷阱
· .NET8带来的一些新特性
阅读排行:
· 1 分钟生成架构图?程序员 AI 绘图保姆级教程
· 字符集、编码的前世今生
· 一种更简单的方式运行 C# 代码,简化 C# 开发体验!
· 最快的流媒体服务器搭建 smart_rtmpd
· 高并发下如何防止商品超卖?
< 2025年6月 >
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 1 2 3 4 5
6 7 8 9 10 11 12

导航

统计

点击右上角即可分享
微信分享提示