1.裸
- [POJ2976]Dropping tests
题目大意:给出序列(a,b)求,去掉任意(k)个对应的(a_i, b_i)使得剩下的(100*frac{sum_{i=1}^{n-k}a_i}{sum_{i=1}^{n-k}b_i})最大,求这个最大值
bool check(double mid){
for(int i=1; i <= n; i++) c[i]=100*a[i]-mid*b[i];
sort(c+1, c+1+n); double sum=0;
for(int i=1; i <= k; i++) sum+=c[n-i+1];//这里的k为n-k
return sum > 0;
}
double eps=1e-4;
void cal(){
double l=0.0, r=100.0;
while(r-l > eps) {double mid=(l+r)/2; if(check(mid)) l=mid; else r=mid;}
printf("%.0f
", l);
}
2.最优比率生成图
- [POJ2728]Desert King
(我不会说我是现学的prime)
题目大意:给出有(N)个点的无向图,每个点有一个海拔高度,任意两点间连有一条边,边长(R_e)为两点间的水平距离,边权为(C_e),求此图的生成树(G),使得(sum_{ein G}C_e/R_e)最小,输出这个最小值
令(W_e=R_e imes ans-C_e),二分(ans),只要(forall G)使得(sum_{ein G}W_e >= 0) 那么,这个(ans)就是可行解,则求图的最大生成树即可
bool check(double mid){
for(int i=1; i <= n; i++) for(int j=i+1; j <= n; j++)
w[i][j]=w[j][i]=mid*len[i][j]-cost[i][j];
double sum=0; memset(vis, 0, sizeof(vis)); memset(d, -0x3f3f3f3f, sizeof(d)); d[1]=0;
for(int i=1; i < n; i++){
int x=0;
for(int j=1; j <= n; j++) if(!vis[j] && (!x || d[j] > d[x])) x=j;
vis[x]=1;
for(int j=1; j <= n; j++) if(!vis[j]) d[j]=max(d[j], w[x][j]);
}
for(int i=2; i <= n; i++) sum+=d[i];
return sum > 0;
}
double eps=1e-6;
void cal(){
double l=0.0, r=100;
while(r-l > eps){
double mid=(l+r)/2;
if(check(mid)) r=mid; else l=mid;
}
printf("%.3f
", l);
}