XJOI NOIP2016提高组冲剌题1 T1:挖金矿
题目分析:
一开始的时候思考是否能否用贪心做,但是后来暴力对拍验证挂掉了.
考完之后发现其实可以用二分答案,那么对于答案ans,则有
h[i]表示第i列挖的深度,sum[i][j]表示第i列挖了j深度得到的总价值.
时间复杂度为O(nlogn*h)
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef double db;
const int maxn=100000+10;
int n,m;
db A[maxn];
bool check(db ans)
{
db sum=0;
for(int i=1;i<=n;i++) {
int cur=(i-1)*m;
db now=A[cur+1];
db maxs=now-ans;
for(int j=2;j<=m;j++) {
now+=A[cur+j];
maxs=max(maxs,now-ans*j);
}
sum+=maxs;
}
return sum>=0;
}
db work(db l,db r)
{
db ans=0;
while(r-l>0.000001) {//浮点数二分答案,注意循环条件
db mid=(l+r)/2;
if(check(mid)) ans=l=mid;
else r=mid;
}
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
db l=0,r=0;
for(int i=1;i<=n*m;i++) scanf("%lf",&A[i]),r=max(r,A[i]);
db ans=work(l,r);
printf("%.4lf",ans);
return 0;
}