码迷,mamicode.com
首页 > 其他好文 > 详细

弹珠(贪心+二分)

时间:2018-06-29 00:14:57      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:show   数据   www   证明   font   分数   bubuko   分享   结构   

https://www.luogu.org/problemnew/show/T32708

这道题是校模拟的一道题,

本来的朴素想法是贪心,当时得了40分,但是程序很乱

第二次修改了数据结构,程序变得清爽许多,但是分数没有改变,后来手动加了一个特判多了二十

第三次按照正解的思路但是仍然出了一点小bug,最后成功

首先用贪心的时候要做一个简单的正确性证明,可以举几个特殊的例子,

正确的做法应该是二分然后不断逼近,技术分享图片

 

标程

//原本是说b总和除以w总和的最大值,将其转换为b-x*w,
//算其余下多少,不断接近
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
struct date{
int wz,bz;
float v;
}g[1200];
int w[6000],b[6000];//b是美丽值,w是重量
float ps[1200];
int n,m,k;
int w2,b2;
float v2;
int ok(float x){
for(int i=1;i<=m;i++)ps[i]=(float)(g[i].bz-x*g[i].wz);
sort(ps+1,ps+1+m);//n,m错
// for(int i=m;i>=1;i--)
// cout<<ps[i]<<" ";
float tot=0;
for(int i=m;i>=m-k+1;i--)tot+=ps[i];//n,m错
return tot>=0;
}
void solve(){
float l=0,r=1500;
while((r-l)>1e-3){//应用二分计算
float mid=(l+r)/2.0;
if(ok(mid))l=mid+1e-3;
else r=mid-1e-3;
}
printf("%.2f",(l+r)/2.0);
}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
int x;
for(int i=1;i<=m;i++){
scanf("%d",&x);
while(x){
g[i].wz+=w[x];
g[i].bz+=b[x];
scanf("%d",&x);
}
}
solve();
return 0;
}
/*学姐的更优雅的二分写法
float l=0,r=1500;
for(int time=0;time<=100;time++){
float mid=(l+r)/2.0;
if(ok(mid))l=mid;
else r=mid;
}
printf("%.2f",(l+r)/2.0);

弹珠(贪心+二分)

标签:show   数据   www   证明   font   分数   bubuko   分享   结构   

原文地址:https://www.cnblogs.com/linzeli/p/9241193.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!