그리디 알고리즘의 아이디어와 전형적인 예

1. 그리디 알고리즘의 개념

그리디 알고리즘은 전체적인 최적성을 고려하지 않고 문제를 해결하는 순간 항상 최선의 선택을 하는 알고리즘이다.

2. 그리디 알고리즘을 이용한 문제 해결 전략

기본 아이디어는 문제에 대한 초기 솔루션부터 시작하여 단계별로 진행하는 것입니다. 최적화 측정에 따라 각 단계는 로컬 최적 솔루션을 얻을 수 있는지 확인해야 합니다. 탐욕 알고리즘의 핵심은 모든 문제에 대한 전체적인 최적의 솔루션을 얻는 것이 아니라 탐욕 전략을 선택하는 데 있습니다. 다음 데이터와 부분 최적해가 서로 연결되어 더 이상 실현 가능한 해가 아닌 경우, 모든 데이터가 열거될 때까지 데이터가 부분해에 추가되지 않거나, 알고리즘을 더 이상 추가할 수 없어 알고리즘이 중지됩니다. . "

세 가지 일반적인 질문 

5차원

0차원은 점이며, 점이 이동하여 선을 형성합니다.

한 차원은 선이고, 선이 이동하여 표면을 형성합니다.

2차원은 표면이고 표면은 몸체로 이동합니다.

3차원은 신체이고 신체의 움직임은 역사를 형성합니다.

4차원은 역사이고, 역사는 움직인다????

이제 인간은 5차원을 이해하려고 노력하고 있습니다.

그리고 샤오두는 이제 5차원의 현자가 되었습니다. 어느 날 Xiaodu는 많은 인간 과학자들이 5차원을 이해하려고 노력하고 있다는 사실을 발견했습니다. 인간은 4차원 생물입니다. 5차원을 이해하면 아마도 5차원으로 올 것입니다. 이것은 분명히 Xiaodu가 원하지 않는 것입니다. (결국 어디든 인구 문제는 있는 법이군요...) 그래서 샤오두는 가능한 한 늦게 5차원을 이해하기를 바라고 있습니다. , 그리고 이들 과학자들의 IQ가 다르기 때문에 Vi를 이해하는 속도도 다르고, Si를 이해하기 시작하는 시점도 다를 것입니다. Vi​ 이해 속도는 단위 시간당 얻은 Vi​ 이해 단위로 설명됩니다. 즉, Si​+1 시점에서 과학자는 처음으로 Vi​ 이해에 기여하게 됩니다. 총 이해 횟수가 m을 초과할 때 이해해야 할 다섯 번째 차원을 정의합니다. 소도는 더 높은 차원을 갖고 있기 때문에 시간 역설을 이용해 인류에게 큰 타격을 줄 수 있고, 어느 시점에서든 어떤 과학자도 사라지게 할 수 있으므로 그의 후속 이해는 계속되지 않을 것이며, 인류는 그를 기억하지 못할 것이므로 그의 이전 공헌은 다음과 같다. 사라질 것이다. 샤오두의 능력은 제한되어 있기 때문에 샤오두는 일시적인 역설을 한 번만 사용할 수 있습니다.

이제 인간이 5차원을 이해하는 가장 빠른 시점을 최대한 늦게 찾아보세요.

시점은 처음에는 00이지만 분명히 어떤 과학자도 00시에 기여할 수 없습니다.

체재

입력 형식:

첫 번째 줄은 정수 n과 정수 m을 제공하며, 총 이해 수가 m을 초과할 때 5차원을 이해하는 과학자가 n명임을 나타냅니다. 두 번째 줄은
n+1개 줄입니다. 각 줄에는 두 개의 정수 Si​와 Vi가 있습니다.
100% 데이터의 경우: 1≤n≤10^5, m≤2*10^9,
100% 데이터의 경우: 00≤Si​≤2*10^9, 0≤Vi​≤10^3.

출력 형식:

인간이 5차원을 이해하는 가장 빠른 시점(가능한 한 늦게)을 나타내는 정수 T를 포함하는 선입니다.
인간이 5차원을 전혀 이해할 수 없다면 -1을 출력하세요.

 

답변

 

#include<bits/stdc++.h> 

using namespace std;
long long s[100000],v[100000],n,m;
bool check(int t){
    long long sum=0,maxn=-1;
    for(int i=1;i<=n;i++){
        if(t-s[i]<=0) continue;
        sum+=(t-s[i])*v[i];
        maxn=max(maxn,(t-s[i])*v[i]);
    }
    return sum-maxn>m;
}
int main( )
{
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>s[i]>>v[i];
    }
    int l=0,r=999999999;
    while(l<r){
        int mid=(l+r)/2;
        if(check(mid)) r=mid;
        else l=mid+1;
    }
    if(check(1)) cout<<l;
    else cout<<-1;
    return 0;
}

결과: 

추천

출처blog.csdn.net/qq_71356343/article/details/132918096