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; }