• 备战蓝桥杯---贪心刷题1


    话不多说,直接看题:

    本质是一个数学题:

    我们令xi<0表示反方向传递,易得我们就是求每一个xi的绝对值之和min,我们令平均值为a爸。

    易得约束条件

    x1-x2=a1-a,x2-x3=a2-a.....

    解得x1=x1-0,x2=x1-((n-1)*a-a2-...an)。。。。

    这样就把问题转化成|x1-c1|+|x2-c2|+|...|....

    又ci=ci+1+a-ai我们就可以吧c解出来,下面是AC代码:

    1. #include
    2. using namespace std;
    3. const int N=1000010;
    4. long long n,a[N];
    5. long long sum=0;
    6. long long c[N];
    7. int main(){
    8. cin>>n;
    9. for(int i=1;i<=n;i++){
    10. scanf("%lld",&a[i]);
    11. sum+=a[i];
    12. }
    13. long long av=sum/n;
    14. for(int i=n;i>1;i--){
    15. c[i]=c[i+1]+av-a[i];
    16. }
    17. c[1]=0;
    18. sort(c+1,c+n+1);
    19. long long res=0;
    20. for(int i=1;i<=n;i++) res+=abs(c[i]-c[(i+1)/2]);
    21. cout<
    22. }

    接题:

    先转换一下,我们从小岛的角度来看,看看每一个小岛可以被覆盖在x轴上对应的范围,这样问题就转换成了给定若干个区间,最少选多少个点可以使得每一个区间至少选了一个点。

    如何贪心?我们先按照右端点排序,扫描每一个线段,若上一个右端点不在区间,那么选右端点。

    若在则跳过。

    如何严格证明?

    我们记cnt为算法得到的结果,opt为最优解。

    显然选了cnt个,那么就有cnt个互不相交的区间,因此答案一定大于等于cnt+opt是最优解,得证!

    下面是AC代码:

    1. #include
    2. using namespace std;
    3. const int N=1010;
    4. int n,d;
    5. struct node{
    6. double l,r;
    7. }seg[N];
    8. bool cmp(node a,node b){
    9. return a.r
    10. }
    11. int main(){
    12. cin>>n>>d;
    13. bool ff=0;
    14. for(int i=0;i
    15. int x,y;
    16. scanf("%d%d",&x,&y);
    17. if(y>d) ff=1;
    18. else{
    19. double ck=sqrt(d*d-y*y);
    20. seg[i].l=x-ck,seg[i].r=x+ck;
    21. }
    22. }
    23. if(ff) cout<<-1<
    24. else{
    25. sort(seg,seg+n,cmp);
    26. int cnt=0;
    27. double last=-1000000000;
    28. for(int i=0;i
    29. if(last
    30. cnt++;
    31. last=seg[i].r;
    32. }
    33. }
    34. cout<
    35. }
    36. }

    接题:

    很容易想到,假如每一个人的钱都比平均大,那么都取平均即可。

    假如有一个人少,那么让它填满,剩下的平均分摊给大于平均的。

    下面是严格的证明:

    我们把方差的每一项看成xi,xi的和为0,由均值不等式知我们要让每一个数尽可能相同,假如有一个小于平均值,假设它不选满,则结果肯定变大。

    因此,若a1<平均值,那么我们就取a1,后面的式子满足加起来和为s-a1,因此剩下的加起来就是s-a1-(n-1)/n*s;此时每一个取到(s-a1)/(n-1)是最优的,而若此时大于该值,那么后面的肯定也大(排过序),因此取其即可。

    下面是AC代码:

    1. #include
    2. using namespace std;
    3. const int N=500100;
    4. int n,a[N];
    5. int main(){
    6. long double s;
    7. scanf("%d%Lf",&n,&s);
    8. for(int i=0;iscanf("%d",&a[i]);
    9. sort(a,a+n);
    10. long double res=0,av=s/n;
    11. for(int i=0;i
    12. double cur=s/(n-i);
    13. if(a[i]
    14. res+=(cur-av)*(cur-av);
    15. s-=cur;
    16. }
    17. printf("%.4Lf\n",sqrt(res/n));
    18. }

  • 相关阅读:
    day41 jdk8新特性Stream流 数据库安装
    知识蒸馏3:YOLOV5项目准备
    pytest+requests+allure自动化测试接入Jenkins学习
    SQL 查询并拼接字段的两种方法主要用于多级分类表格显示(一级/二级/三级/)
    Spring Cloud Hystrix:服务容错保护
    优化理论笔记
    增删查改dom节点的操作
    Aspose.Words for .NET图表教程——如何设置图表轴属性
    EMNLP 2022 | SentiWSP: 基于多层级的情感感知预训练模型
    【python】pandas 索引操作
  • 原文地址:https://blog.csdn.net/cocoack/article/details/137204292