【GDOI 2016 Day1】第一题 中学生数学题

Description

给定商品成本 p0 和系数 k ,常数 n0 ,设价格为 p ,购买商品人数满足n1 = n0 -k*p 其中 p , k 为实数, 0 n 为整数。
题目分为两部分:
1)可以设置一个价格,求最大利润。
2)可以设置两个价格, p1 , p2 ,有 n1 = n0-k*p1 的人按 p1 购买,n2= n0-k*p2 -n1 按 p2 购买,求最大利润。

题解:

解法一:因为是单峰函数,所以很显然可以用三分求出极值,但
是实现细节比较复杂。
解法二:最直观的想法是直接枚举 p ,求最大值。但是 p 是实
数,精度什么的不好处理。我们以 n1 为自变量,枚举 n1 的取值,
然后求最大值。第二部分也类似,枚举 n1 ,然后可以得到一个关
于 n2 的二次函数,这时直接用二次函数的相关知识就能求出最大
值(对称轴x=- b2a )
解法三:对于第一部分还有一个更简单的解法,直接可以从图像
中发现,当 p 取中点的时候利润是最大的。所以只需要取中点
和其上下取整的最大值就是答案。

这里重点介绍第二种解法:

补充一下一元二次函数求最值方面的知识

二次函数一般式为: y=ax2+bxc
顶点坐标:( b2a , 4acb24a )

二次函数
y=ax²+bx+c =a(x+ b2a )²+c- b24a (a≠0)
这里其实是跳步了,从前式转到后式,是用配方法转移的。
原式=a( x2+bax )+c
=a( x2+bax+b24a2 )+c- b24a
= a(x+b2a)2+cb24a

当a>0时二次函数图象开口向上,其有最小值
当x=-b/2a时 ymin=cb24a=4acb²4a
当a<0时二次函数图象开口向下,其有最大值
当x=-b/2a时 ymax=cb24a=4acb24a

x=b2a 可以使y取得最大或最小值
(1)当a>0时,抛物线的开口向上,y有最小值.
(2)当a<0时,抛物线的开口向下,y有最大值.
x=b2a 代入2次函数一般式即可求得y的极值(这是一般的做法)

另一种做法是配方法
把y表示成〔1〕 y=(kx+b)(kx+b)+h 或 〔2〕 y=(kx+b)(kx+b)+h
当kx+b=0时,明显看出〔1〕取得最小值,〔2〕取得最大值
其实配方法的本质就是第一种做法
a>0时开口向上,有最小值,当 x=b2a 时,取得最小值为 y=(4acb2)/4a
a<0时开口向下,有最大值,当 x=b2a 时,取得最大值为 y=(4acb2)/4a

Attached CODE

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define fo(i,a,b) for (int i=a;i<=b;i++)
using namespace std;
double Profit_ans1,Profit_ans2,p,k;
int n;
double Calculation(int x,int y)
{
    double p2=(double)(x+y-n)/(-k);
    return ((double)y*(p2-p));
}
int main()
{
    freopen("math.in","r",stdin);
    freopen("math.out","w",stdout);
    scanf("%d%lf%lf",&n,&p,&k);
    fo(n1,0,n)
    {
        double P1=(double)(n-n1)/k;
        double Profit=(double)(n1*(P1-p));
        Profit_ans1=max(Profit_ans1,Profit);
        double Tqy=(double)(P1-p);
        int x=-Tqy/((double)(-1.0)/k*2.0);
        double Lqy=Calculation(n1,x-1);
        Lqy=max(Lqy,Calculation(n1,x));
        Lqy=max(Lqy,Calculation(n1,x+1));
        Profit+=Lqy;
        Profit_ans2=max(Profit_ans2,Profit);
    }
    printf("%.3lf %.3lf",Profit_ans1,Profit_ans2);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值