Description
Analysis
这道题很容易误入歧途:以为每列取平均最大的就是全局最大的。
我这个小doby就掉坑里了。
反例数据:
2 5
1 9
1 1
1 1
1 1
2 1
最优:每列只取一个;贪心:第一列全部取完了。
比赛时后来就方方方,毫无思路。。。
正解二分答案。
以后记住一点:毫无思路的题想想能不能二分转化为判定性问题。
二分答案,如果当前答案可行,则:
∑ni=1sum[i][h[i]]∑ni=1h[i]≥mid
移项
∑ni=1sum[i][h[i]]−h[i]∗mid≥0
那么这时候就可以贪心了,每一列选最大的,加起来看看是否大于零就行了。
O(nmlogAns)
Code
#include<cstdio>
#include<vector>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef double db;
const int N=100010,INF=1000000000;
const db eps=1e-5;
int n,m;
vector<db> a[N];
bool check(db x)
{
db t=0,mx;
fo(i,1,n)
{
mx=-INF;
fo(j,0,a[i].size()-1)
mx=max(mx,a[i][j]-(j+1)*x);
t+=mx;
}
return t>0;
}
int main()
{
db x;
scanf("%d %d",&n,&m);
fo(i,1,n)
{
db sum=0;
fo(j,1,m)
{
scanf("%lf",&x);
sum+=x;
a[i].push_back(sum);
}
}
db l=0,r=INF;
while(r-l>eps)
{
db mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
printf("%.4lf",l);
return 0;
}