Codeforces Round #477 (rated, Div. 2, based on VK Cup 2018 Round 3) D 贪心

http://codeforces.com/contest/967/problem/D

 

 

Topic meaning:

There are n servers, labeled 1~n, and each server has C[i] resources. Now, there are two tasks that need to be performed at the same time, let him be x1, x2.

Conditions to run the task:

①Each server can only run one task at the same time

②The task can be assigned to multiple servers for execution at the same time. Assuming that the task x1 is allocated to a number of servers, each server needs to use the resources of x1/a (this resource can be a decimal)

QCan the above conditions be met so that x1 and x2 can run in the server at the same time?

 

 

Ideas:

Arrange all servers in increasing order of resources, and define dp(i) to represent the resource provision from the i-th server to the n-th server, that is, dp[i] = (n - i + 1) * c[i];

Next, violently once again 1~n,

When dp(i)>=x1 is satisfied, take the least satisfying c(i) * cnt >= x1 greedily

Then use dp to find the conditions that satisfy x2.

 

// See if it will explode int! Will the array be one dimension less!
// The fetch problem must be careful of the conditions for the first mover to win
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = 1e6 + 5;
int n, x1,x2;
vector<pair<int, int> > ve;
int dp[maxn];
pair<int, int> ans1, ans2;

bool check(int i, int x1, int x2){
    int cnt1 = x1 / ve[i].fi;
    if (x1 - cnt1 * ve[i].fi > 0) cnt1++;
    if (dp[i + cnt1] >= x2) {
        ans1 = mk (i, i + cnt1 - 1 );
        ans2.fi = i + cnt1;
        int cnt2 = x2 / ve[i+cnt1].fi;
        if (x2 - cnt2 * ve[i+cnt1].fi > 0)
            cnt2 ++ ;
        ans2.se = ans2.fi + cnt2 - 1;
        return true;
    }
    return false;
}

bool solve(){
    bool flag = false;
    for (int i = 0; i < ve.size(); i++){
        if (dp[i] >= x1){
            if (check(i, x1, x2)) flag = true;
        }
    }
    if (flag == false){
        swap(x1, x2);
        for (int i = 0; i < ve.size(); i++){
            if (dp[i] >= x1){
                if (check(i, x1, x2)) {
                    flag = true;
                    swap(ans1, ans2);
                }
            }
        }
    }
    if (flag){
        puts("Yes");
        printf("%d %d\n", ans1.se - ans1.fi + 1, ans2.se - ans2.fi + 1);
        for (int j = ans1.fi; j <= ans1.se; j++)
            printf("%d ", ve[j].se);
        cout << endl;
        for (int j = ans2.fi; j <= ans2.se; j++)
            printf("%d ", ve[j].se);
        cout << endl;
        return true;
    }
    return false;
}

int main(){
    cin >> n >> x1 >> x2;
    for (int i = 1; i <= n; i++){
        int a; scanf("%d", &a);
        ve.pb(mk(a, i));
    }
    sort(ALL(ve));
    for (int i = ve.size()-1; i >= 0; i--){
        dp[i] = (ve.size() - i) * ve[i].fi;
    }
    if (solve() == false) puts("No");
    return 0;
}
View Code

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325114948&siteId=291194637