良いの半分のタイトル

、半分は、番号を見つけるために最小値を最大化すると、この数より全て満たすの大きい数であり、この数は最小であり、その後の数半分の最大値を見つける
最小値の半分は、最大の最大値を最小化することができます
ポータル

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#define ll long long
const int maxn = 5e4+500;
const int inf = 0x3f3f3f3f;
const double eps = 1e-5;
using namespace std;
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    return f*x;
}
ll a[maxn];
int n,d;
int day[maxn];
bool check(ll x){//每天都需要达到这么多的开心值
    ll sum=0;//每天的开心值
    int k=0;
    for(int i=1;i<=d;i++){
        while(sum<x){
            k++;
            sum+=a[k];
            if(k>n)return 0;//巧克力不够吃了
        }
        sum/=2;
    }
    return 1;
}
void getans(ll x){//每天吃的值
    ll sum=0;
    int k=0;
    for(int i=1;i<=d;i++){
        while(sum<x){
            k++;
            sum+=a[k];
            day[k]=i;
        }
        sum/=2;
    }
}
int main(){
    cin>>n>>d;
    ll l=0,r=0;
    for(int i=1;i<=n;i++)a[i]=read(),r+=a[i];
    ll mid=0;
    ll ans=0;
    while(l<=r){
        mid=(l+r)/2;
        if(check(mid)){//找到一个最小值,每天都吃后的值都≥这个值
            l=mid+1;
            ans=mid;
        }else r=mid-1;
    }
    printf("%lld\n",ans);
    getans(ans);
    for(ll i=1;i<=n;i++){
        if(day[i])printf("%d\n",day[i]);
        else printf("%d\n",d);
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/Emcikem/p/11806971.html