Description
题目大意就是给你整数
n0
,实数
p0,k
求一个
p
,使
再求
p1,p2
,使
⌊n0−kp1⌋(p1−p0)+⌊n0−kp2−⌊n0−kp1⌋⌋(p2−p0)
最大
Solution
显然 kp 为整数更优。
那么我们只考虑
kp
为整数的情况,易发现答案与
p
成一个二次函数(然而我居然把式子忘了)
那么第一问我们搞一个三分即可
对于第二问,三分
不知道三分的戳这里
>
然而,我们有一种更简单的方法。
设
n=⌊n0−kp⌋
我们画出以
p
为
我们要求的就是这个蓝色矩形的最大面积
这里我们应该取中点(证明自己YY),然后再 ±1 取最大即可
对于第二问
我们要求这个蓝色图形的面积
于是我们应该取三等分点(证明继续自己YY),然后再 ±1 取最大即可
当时左评委讲解的时候我们都惊呆了~~
复杂度是常数级的,精度自己看着办
Code
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
using namespace std;
double p0,k,p1;
int n1,n2,n0,n3;
int main()
{
cin>>n0>>p0>>k;
n1=n0-trunc(n0-k*p0)/2;
int i,j;
double ans=0;
fo(i,n1-1,n1+1)
{
ans=max(ans,(i/k-p0)*(n0-i));
}
printf("%.3lf ",ans);
n2=trunc(n0-k*p0)/3;
ans=0;
fo(i,n2-1,n2+1)
{
n3=n2;
fo(j,n3-1,n3+1)
{
ans=max(ans,((n0-i)/k-p0)*i+((n0-i-j)/k-p0)*j);
}
}
printf("%.3lf ",ans);
}