Codeforces Round # 555 (Div. 3) D. N tasks for K days (构造)

题目链接:http://codeforces.com/contest/1157/problem/D

题意:给定N个任务,K天完成。a[i]为第k天完成的任务数量。a[i]满足条件:a[i] < a[i] <= 2 * a[i + 1]

k天内能完成的最少任务数为1开始的等差数列:k * (k + 1) / 2,只要k * (k + 1) / 2 > n则肯定不存在这样的安排

n - k * (k + 1) / 2为剩余要安排的任务,平均地放到k天里面,有可能放到k天里面会有一些余数,我们从最后一天开始往前面安排这些余数。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <queue>
#include <climits>
#include <set>
#include <stack>
#include <string>
#include <map>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
static const int MAX_N = 1e5 + 5;
static const ll Mod = 2009;
int ans[MAX_N];
void solve(){
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
    int n, k;
    while(scanf("%d%d", &n, &k) != EOF){
        ll minv = 1LL * k * (k + 1) / 2;
        if((ll)n < minv) puts("NO");
        else{
            int remv = n - minv;
            int avg = remv / k;
            for(int i = 1; i <= k; ++i) ans[i] = avg + i;
            remv %= k;  //安排余下任务数
            for(int i = k; i >= 1 && remv; --i){
                while(remv && (i == k || ans[i] + 1 < ans[i + 1]) && (i == 1 || ans[i] < 2 * ans[i - 1])){
                    ++ans[i];
                    --remv;
                }
            }
            if(remv) puts("NO");
            else{
                puts("YES");
                for(int i = 1; i <= k; ++i) printf("%d%c", ans[i], i == k ? '\n' : ' ');
            }
        }
    }
}
int main() {
    solve();
    return 0;
}
View Code

 

posted @ 2019-06-02 15:27  html_11  阅读(171)  评论(0编辑  收藏  举报