codeforces 985C Liebig's Barrels

题意:

有n * k块木板,每个木桶由k木板组成,每个木桶的容量定义为它最短的那块木板的长度。

任意两个木桶的容量v1,v2,满足|v1-v2| <= d。

问n个木桶容量的最大的和为多少,或者说明不可能做出这样的n个木桶。

思路:

贪心

要满足|v1-v2| <= d,那么就要满足最大的木桶容量和最小的木桶容量的差小于等于d。

所以先把木板长度排序,如果a[0] 到 a[0] + d这个范围内有大于等于n个木板,那么就存在合理的分配方案,因为可以把至少n个木板作为最短的木板。

然后就计算最大的和,如果a[0] 到 a[0] + d这个范围内刚好有n块木板,那么最大的和就是这n块木板长度的和;

如果大于n的话,那么就要考虑让每个木桶最小木板的长度尽可能的大,就是让每个最小木板尽选择数组后面的数字。

因为1块木板可以支配k - 1块木板,所以下一个木桶的最小长度就可以从a[k]开始,这样就让最小的尽量大了。

一个木板可以覆盖的区间长度是k,假设a[0] 到 a[0] + d这个范围内有sum块木板,那么多余的木板就是res = sum - n。

区间数量就是c = res / (k-1),设r = res / (k - 1),

当r = 0,那么就有c个完整的区间,前c个木桶的长度就是0*k,1*k,2*k . . . (c-1)*k,后n - c个木桶的容量的下标就从c * k到sum-1;

当r != 0,有c个完整的区间和一个不完整的区间,前c + 1个木桶的容量就是0 * k,1 * k,2 * k . . . c * k,后n - c - 1个木桶的容量的下标就从c * k + r + 1到sum - 1。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N = 1e5 + 10;
 6 long long a[N];
 7 int main()
 8 {
 9     int n,k;
10     long long l;
11     scanf("%d%d%lld",&n,&k,&l);
12     for (int i = 0;i < n * k;i++) scanf("%lld",&a[i]);
13     sort(a,a+n*k);
14     //printf("%lld\n",a[0] + l);
15     int pos = upper_bound(a,a+n*k,a[0] + l) - a;
16     pos--;
17     //printf("%d\n",pos);
18     if (pos < n - 1) puts("0");
19     else
20     {
21         long long ans = 0;
22         int sum = pos + 1;
23         if (sum == n)
24         {
25             for (int i = 0;i < n;i++) ans += a[i];
26         }
27         else
28         {
29             if (k == 1)
30             {
31                 for (int i = 0;i < n;i++) ans += a[i];
32             }
33             else
34             {
35                 int c = (sum - n) / (k - 1);
36                 int r = (sum - n) % (k - 1);
37                 if (r)
38                 {
39                     for (int i = 0;i <= c;i++)
40                     {
41                         ans += a[i*k];
42                     }
43                     n -= c + 1;
44                     for (int i = k * c + r + 1;i <= pos;i++)
45                     {
46                         if (n == 0) break;
47                         ans += a[i];
48                         n--;
49                     }
50                 }
51                 else
52                 {
53                     for (int i = 0;i < c;i++)
54                     {
55                         ans += a[i*k];
56                     }
57                     n -= c;
58                     for (int i = k * c;i <= pos;i++)
59                     {
60                         if (n == 0) break;
61                         ans += a[i];
62                         n--;
63                     }
64                 }
65             }
66         }
67         printf("%lld\n",ans);
68     }
69     return 0;
70 }

codeforces 985C Liebig's Barrels

原文地址:https://www.cnblogs.com/kickit/p/9070612.html

时间: 2024-08-01 07:57:28

codeforces 985C Liebig's Barrels的相关文章

codeforce 985C Liebig&#39;s Barrels(贪心+思维)

Liebig's Barrels time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You have m?=?n·k wooden staves. The i-th stave has length ai. You have to assemble n barrels consisting of k staves each, y

【codeforces 768F】 Barrels and boxes

http://codeforces.com/problemset/problem/768/F (题目链接) 题意 A,B两种物品可以装到栈中,每个栈只能存放一种物品,容量没有限制.现在讲所有栈排成一列,AB相间,问存B的栈长大于H的概率. Solution 震惊!F竟是个大水题...枚举长度隔板法搞一搞就好了.. 细节 注意判0分成0组的情况?LL 代码 // codeforces768F #include<algorithm> #include<iostream> #includ

【codeforces 718E】E. Matvey&#39;s Birthday

题目大意&链接: http://codeforces.com/problemset/problem/718/E 给一个长为n(n<=100 000)的只包含‘a’~‘h’8个字符的字符串s.两个位置i,j(i!=j)存在一条边,当且仅当|i-j|==1或s[i]==s[j].求这个无向图的直径,以及直径数量. 题解:  命题1:任意位置之间距离不会大于15. 证明:对于任意两个位置i,j之间,其所经过每种字符不会超过2个(因为相同字符会连边),所以i,j经过节点至多为16,也就意味着边数至多

Codeforces 124A - The number of positions

题目链接:http://codeforces.com/problemset/problem/124/A Petr stands in line of n people, but he doesn't know exactly which position he occupies. He can say that there are no less than a people standing in front of him and no more than b people standing b

Codeforces 841D Leha and another game about graph - 差分

Leha plays a computer game, where is on each level is given a connected graph with n vertices and m edges. Graph can contain multiple edges, but can not contain self loops. Each vertex has an integer di, which can be equal to 0, 1 or  - 1. To pass th

Codeforces Round #286 (Div. 1) A. Mr. Kitayuta, the Treasure Hunter DP

链接: http://codeforces.com/problemset/problem/506/A 题意: 给出30000个岛,有n个宝石分布在上面,第一步到d位置,每次走的距离与上一步的差距不大于1,问走完一路最多捡到多少块宝石. 题解: 容易想到DP,dp[i][j]表示到达 i 处,现在步长为 j 时最多收集到的财富,转移也不难,cnt[i]表示 i 处的财富. dp[i+step-1] = max(dp[i+step-1],dp[i][j]+cnt[i+step+1]) dp[i+st

Codeforces 772A Voltage Keepsake - 二分答案

You have n devices that you want to use simultaneously. The i-th device uses ai units of power per second. This usage is continuous. That is, in λ seconds, the device will use λ·ai units of power. The i-th device currently has bi units of power store

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp

Codeforces Round #408 (Div. 2) B

Description Zane the wizard is going to perform a magic show shuffling the cups. There are n cups, numbered from 1 to n, placed along the x-axis on a table that has m holes on it. More precisely, cup i is on the table at the position x?=?i. The probl