二分专项

二分搜索

二分搜索的板子:(左闭右开)
对于其他的二分情况可以参考https://blog.csdn.net/CCSGTC/article/details/80586181

在二分过程中,始终维持左闭右开的条件

void solve(){
    sort(heig,heig+n);
    int left = 0, right = 1000000001; // [0,1000000001)
    while(left+1<right){
        int mid = (left+right)/2;
        if(fuc(mid)) left = mid;
        else right = mid;
    }
    printf("%d\n",left);
}

最终边界条件:
(图片来源)https://oi-wiki.org//basic/binary/
在这里插入图片描述
二分裸题 https://www.luogu.org/problemnew/show/P1873

二分其中的可能性即可

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

int n,m;
int heig[1000010];

void get_data(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d",&heig[i]);
    }
}

bool fuc(int mid){
    long long ans = 0;
    for(int i=n-1;heig[i]>mid;i--){
        ans += heig[i]-mid;
    }
    return ans>=m;
}

void solve(){
    sort(heig,heig+n);
    int left = 0, right = 1000000001;
    while(left+1<right){
        int mid = (left+right)/2;
        if(fuc(mid)) left = mid;
        else right = mid;
    }

    printf("%d\n",left);
}

int main() {
    get_data();
    solve();
    return 0;
}

分数规划

基础:https://blog.csdn.net/hzoi_ztx/article/details/54898323

裸题 : https://vjudge.net/problem/POJ-2976

特别提醒程序退出条件 (都是泪啊)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;


int n,k;
int a[1010],b[1010];

void get_data(){
    for(int i=0;i<n;i++) cin>>a[i];
    for(int i=0;i<n;i++) cin>>b[i];
}

bool judge(double mid){
    double result[1010];

    double ans = 0;
    for(int i=0;i<n;i++) result[i] = a[i] - mid*b[i];
    sort(result,result+n);
    for(int i=n-1;i>=k;i--) ans += result[i];
    return ans>=0;
}

void solve(){
    double left = 0, right = 1e8;
    while(right-left>1e-6){
        double mid = (right+left)/2;
        if(judge(mid)) left = mid;
        else right = mid;
    }

    printf("%.0lf\n",100*left);
}


int main(){
    while(cin>>n>>k&&n!=0){  //k是可以等于0而不退出的,,我靠(卡了我2个小时)
        get_data();
        solve();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值