求极值--三分

单调函数求零点用二分,先增后减或先减后增函数求极值用三分

每次检举时,三分是比二分多分了一次,mid=(l+r)/2   rm=(mid+r)/2;

如果mid更靠近极值,则转移为r=rm

如果rm更靠近极值,则转移为l=mid

可行性:

当极值点小于mid时,显然mid会更靠近极值,r=rm转移正确

当极值点大于mid且小于rm时,无论哪个点更靠近极值,无论怎么转移,极值点都还是会在l到r范围内的

当极值点大于rm时,显然rm会更靠近极值,l=mid转移正确


不想用rm=(mid+r)/2  想用lm=(mid+l)/2  。。。。。都是可以的,改一下向下一步转移的地方就行了

三分就和二分一样,最重要的是变通,检举的方法和求哪个方程的极值

zoj 3203 light bulb

Light Bulb

Time Limit: 1 Second       Memory Limit: 32768 KB

Compared to wildleopard's wealthiness, his brother mildleopard is rather poor. His house is narrow and he has only one light bulb in his house. Every night, he is wandering in his incommodious house, thinking of how to earn more money. One day, he found that the length of his shadow was changing from time to time while walking between the light bulb and the wall of his house. A sudden thought ran through his mind and he wanted to know the maximum length of his shadow.

Input

The first line of the input contains an integer T (T <= 100), indicating the number of cases.

Each test case contains three real numbers Hh and D in one line. H is the height of the light bulb while h is the height of mildleopard. D is distance between the light bulb and the wall. All numbers are in range from 10-2 to 103, both inclusive, and H - h >= 10-2.

Output

For each test case, output the maximum length of mildleopard's shadow in one line, accurate up to three decimal places..

Sample Input

3
2 1 0.5
2 0.5 3
4 3 4

Sample Output

1.000
0.750
4.000

在影子没有投到墙上时,影子的长度会随着向墙方向的移动逐渐增大,直到刚好没有投到墙上时,在投到墙上之后,影子的长度变化不是单调的

所以就要用三分求极限

具体离墙的距离对应影子的长度可以用相似三角形求解

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#define eps 1e-9
#define PI 3.141592653589793
#define bs 1000000007
#define bsize 256
#define MEM(a) memset(a,0,sizeof(a))
typedef long long ll;
using namespace std;
double H,h,D;
double solve(double a)
{
	double DD=H*(D-a)/(H-h);
	return (DD-D)*H/DD+a;
}
int main()
{
	int i;
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%lf %lf %lf",&H,&h,&D);
		double l=0,r=D*h/H;
		double mid,mm,ans;
		int size=100;
		while(size--)
		{
			mid=(l+r)/2;
			mm=(mid+r)/2;
			if(solve(mm)>solve(mid))
			{
				ans=mm;
				l=mid;
			}
			else
			{
				ans=mid;
				r=mm;
			}
		}
		printf("%.3lf\n",solve(ans));
	 } 
 }

Error Curves

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 5548    Accepted Submission(s): 2094


Problem Description
Josephina is a clever girl and addicted to Machine Learning recently. She
pays much attention to a method called Linear Discriminant Analysis, which
has many interesting properties.
In order to test the algorithm's efficiency, she collects many datasets.
What's more, each data is divided into two parts: training data and test
data. She gets the parameters of the model on training data and test the
model on test data. To her surprise, she finds each dataset's test error curve is just a parabolic curve. A parabolic curve corresponds to a quadratic function. In mathematics, a quadratic function is a polynomial function of the form f(x) = ax2 + bx + c. The quadratic will degrade to linear function if a = 0.



It's very easy to calculate the minimal error if there is only one test error curve. However, there are several datasets, which means Josephina will obtain many parabolic curves. Josephina wants to get the tuned parameters that make the best performance on all datasets. So she should take all error curves into account, i.e., she has to deal with many quadric functions and make a new error definition to represent the total error. Now, she focuses on the following new function's minimum which related to multiple quadric functions. The new function F(x) is defined as follows: F(x) = max(Si(x)), i = 1...n. The domain of x is [0, 1000]. Si(x) is a quadric function. Josephina wonders the minimum of F(x). Unfortunately, it's too hard for her to solve this problem. As a super programmer, can you help her?
 

Input
The input contains multiple test cases. The first line is the number of cases T (T < 100). Each case begins with a number n (n ≤ 10000). Following n lines, each line contains three integers a (0 ≤ a ≤ 100), b (|b| ≤ 5000), c (|c| ≤ 5000), which mean the corresponding coefficients of a quadratic function.
 

Output
For each test case, output the answer in a line. Round to 4 digits after the decimal point.
 

Sample Input
  
  
2 1 2 0 0 2 2 0 0 2 -4 2
 

Sample Output
  
  
0.0000 0.5000
可以画一画

对所有曲线取一个max之后,是一个凹函数,先减后增,三分求极小值点,对应的极小值也就是答案

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std ;
int n;
double a[10005],b[10005],c[10005];
double solve(double x)
{
    double minn=a[0]*x*x+b[0]*x+c[0];
    for(int i=1;i<n;i++)
    {
        minn=max(minn,a[i]*x*x+b[i]*x+c[i]);
    }
    return minn;
}
int main()
{
    int T,i;
    while(cin>>T)
    {
        while(T--)
        {
            cin>>n;
            for(i=0;i<n;i++)
                scanf("%lf %lf %lf",&a[i],&b[i],&c[i]);
            double ans,le,ri,mid,rm;
            int countt=200;
            le=0.0;
            ri=1000.0;
            while(countt--)
            {
                mid=(le+ri)/2;
                rm=(mid+ri)/2;
                if(solve(mid)<solve(rm))
                {
                    ans=mid;
                    ri=rm;
                }
                else
                {
                    ans=rm;
                    le=mid;
                }
            }
            printf("%.4lf\n",solve(ans));
        }
    }
    return 0;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值