正题
题目大意
给出n0,k,p0n_0,k,p_0n0,k,p0
然后有两问,求
- ⌊n0−kp⌋(p−p0)\lfloor n_0-kp\rfloor (p-p_0)⌊n0−kp⌋(p−p0)的最大值,ppp为任意实数。
- ⌊n0−kp1⌋(p1−p0)+(⌊n0−kp2⌋−n1)(p2−p0)\lfloor n_0-kp_1\rfloor (p_1-p_0)+(\lfloor n_0-kp_2\rfloor -n_1 )(p_2-p_0)⌊n0−kp1⌋(p1−p0)+(⌊n0−kp2⌋−n1)(p2−p0)的最大值其中n1=⌊n0−kp1⌋n1=\lfloor n_0-kp_1\rfloorn1=⌊n0−kp1⌋。p1,p2p_1,p_2p1,p2为任意实数。
解题思路
对于第一问,钦定定义p′=⌊kp⌋p'=\lfloor kp\rfloorp′=⌊kp⌋,然后
⌊n0−kp⌋(p−p0)=−kp2+(n0+kp0)p−n0p0\lfloor n_0-kp\rfloor (p-p_0)=-kp^2+(n_0+kp_0)p-n_0p_0⌊n0−kp⌋(p−p0)=−kp2+(n0+kp0)p−n0p0
转换为p′p'p′
−p′k+(n0k+p0)p′−n0p0-\frac{p'}{k}+(\frac{n_0}{k}+p_0)p'-n_0p_0−kp′+(kn0+p0)p′−n0p0
然后a=−1k,b=n0k+p0,c=−n0p0a=-\frac{1}{k},b=\frac{n_0}{k}+p_0,c=-n_0p_0a=−k1,b=kn0+p0,c=−n0p0
之后用公式−b2a-\frac{b}{2a}−2ab计算出ppp的最优值。
对于第二问,我们可以暴力枚举k∗p1k*p_1k∗p1然后在用公式计算p2p_2p2。
codecodecode
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
double n0,p0,k,ans;
int main()
{//freopen("math.in","r",stdin);//freopen("math.out","w",stdout);scanf("%lf%lf%lf",&n0,&p0,&k);double a=-1/k,b=n0/k+p0,c=-p0*n0;double p=-b/(2*a);printf("%.3lf",(n0-round(p))*(round(p)/k-p0));for(double p1=0;p1<=n0;p1++){double n1=(n0-p1),y=(n0-p1)*(p1/k-p0);double a=-1/k,b=p1/k+p0,c=n0*p1/k-n0*p0-p1*p1/k;double p2=-b/(2*a);ans=max((p1-round(p2))*(round(p2)/k-p0)+y,ans);}printf(" %.3lf",ans);
}