题目描述
分析
因为每个客户都要从第一道菜开始吃
所以最多可以承载的客户数就应该是
b
[
1
]
b[1]
b[1]
接下来就要计算此时最大的收益
因为第
i
i
i道菜如果要被吃,那么之前的
i
−
1
i-1
i−1道菜就都要被吃
所以我们可以求前缀和
然后每次遍历找出最大的前缀和
加到
a
n
s
ans
ans里即可
直到加到第一道菜为止
但是每次要遍历
n
n
n个数,复杂度是
O
(
n
2
)
O(n^2)
O(n2),会超时
所以对于第
i
i
i位,要记录当前最大值的位置,这样可以直接跳到那里
节省了时间
但是
交上去还是WA
这是为什么呢?
发现
n
∗
a
i
∗
b
i
\large n*a_i*b_i
n∗ai∗bi的最大值超过了
l
o
n
g
l
o
n
g
long long
longlong的范围
所以要用高精度
然而我并没有用
查阅资料后发现
l
o
n
g
d
o
u
b
l
e
long\ double
long double型能存的数比
l
o
n
g
l
o
n
g
long\ long
long long大
只要最后不输出小数位即可
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const long double M=1e14+1;
long double a[100100],b[100100],c,o,m;
ll n,i,j,k,l,p,T,q;
long double ans;
struct node
{
long double x;
ll id;
}d[100100];
int main()
{
for (scanf("%lld",&T),q=1;T--;q++)
{
scanf("%lld",&n);
ans=0;k=n+1;o=0;c=0;
memset(d,0,sizeof(d));
memset(b,0,sizeof(b));
d[0].x=-M;
for (i=1;i<=n;i++)
{
scanf("%llf",a+i);
c=c+a[i];
if (c>d[i-1].x)
{
d[i].x=c;
d[i].id=i;
}
else
{
d[i].x=d[i-1].x;
d[i].id=d[i-1].id;
}
}
for (i=1;i<=n;i++)
{
scanf("%llf",b+i);
if (i>1) b[i]=min(b[i-1],b[i]);
}
printf("Case #%lld: ",q);
while(k!=1)
{
for (i=k-1;i!=d[i].id;i=d[i].id);
m=d[i].x;
k=i;
ans=ans+m*(b[k]-o);
o=b[k];
}
cout<<fixed<<setprecision(0)<<b[1]<<" "<<ans<<endl;
}
}