计算机求定积分——自适应辛普森法

例题

洛谷P4526 【模板】自适应辛普森法2
这道题应该不能用牛顿莱布尼兹公式求解,因为这个函数没有初等原函数。(P4525还是算了吧,可以直接查积分表,不过要注意分类讨论)

近似值求法——辛普森法(也叫抛物线法)

辛普森法将定积分范围划分成n个小段,每一段都当做一段抛物线(二次函数)分别求定积分,最后累加起来。

∫ a b f ( x ) d x ≈ b − a 3 n [ ( y 0 + y n ) + 2 ∑ i = 2 n − 2 y i + 4 ∑ i = 1 n − 1 y i ] \int_{a}^{b}f(x)dx \approx \frac{b-a}{3n}[(y_{0}+y_{n})+2\sum_{i=2}^{n-2}y_{i}+4\sum_{i=1}^{n-1}y_{i}] abf(x)dx3nba[(y0+yn)+2i=2n2yi+4i=1n1yi]

#include <bits/stdc++.h>
using namespace std;
double a;
const double INF = 100;
const int n = 1000;
double f(double x)
{
	return pow(x,a/x-x);
}
double Simpson()
{
	double s1 = 0,s2 = 0;
	double h=INF/n;
	for(int k = 1;k <= n-1;k++)
	{
		s1+=f(k*h+h/2);
		s2+=f(k*h);
	}
	s1+=f(INF+h/2);
	return h/6*(4*s1+2*s2+f(INF));
}
int main()
{
	scanf("%lf",&a);
	printf("%0.5lf",Simpson());
	return 0;
}

这样可以得80分。

优化——自适应辛普森法

自适应辛普森法是每次将区间对折为两个,若将整个区间当做抛物线求得的定积分与左右区间分别当做抛物线求得的定积分之和误差不超过最小精度,则返回,否则递归下去。

#include <bits/stdc++.h>
using namespace std;
double a;
double f(double x)
{
	return pow(x,a/x-x);
}
double Simpson(double l,double r)
{
	return (r-l)/6.0*(f(l)+f(r)+4.0*f((l+r)/2.0));
}
double Adaptive(double l,double r,double esp,double ans)
{
	double mid=(l+r)/2.0,lans=Simpson(l,mid),rans=Simpson(mid,r);
	if(fabs(lans+rans-ans)<=esp) return ans;
	else return Adaptive(l,mid,esp,lans)+Adaptive(mid,r,esp,rans);
}
int main()
{
	scanf("%lf",&a);
	if(a<0) printf("orz");
	else printf("%0.5lf",Adaptive(1e-12,20,1e-12,Simpson(1e-12,10)));
	return 0;
}

这样就可以得100分了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值