CF1300E-Water Balance 贪心

我们倒着看,如果当前水桶 比右面水桶多,就把他俩匀一下。然后再往右接着看,如果匀过的这两个比右面第三个大,就把他们三个一起匀一下,复杂度O(N^2)。

我们考虑优化,如果一段被匀了之后,那么他们水位相同,之后要匀也一定是一起匀,就可以看作一个整体了。每个水桶只会被加入到整体一次,我们维护下每一段的开始和长度就可以了。复杂度变为O(N)。

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 int n,to[1100000];
 5 double a[1100000];
 6 int main()
 7 {
 8     scanf("%d",&n);
 9     for (int i = 1;i <= n;i++)
10     {
11         scanf("%lf",&a[i]);
12         to[i] = i;
13     }
14     a[n + 1] = 1100000.0;
15     double tsum;
16     int j,tcnt;
17     for (int i = n;i >= 1;i--)
18     {
19         tsum = a[i];
20         tcnt = 1;
21         j = i + 1;
22         while (a[j] < a[i])
23         {
24             tsum += a[j] * (to[j] - j + 1);
25             tcnt += to[j] - j + 1;
26             a[i] = tsum / tcnt;
27             to[i] = to[j];
28             j = to[j] + 1;
29         }
30     }
31     j = 1;
32     while (j <= n)
33     {
34         for (int i = j;i <= to[j];i++)
35             a[i] = a[j];
36         j = to[j] + 1;
37     }
38     for (int i = 1;i <= n;i++)
39         printf("%.9lf\n",a[i]);
40     return 0;
41 }

猜你喜欢

转载自www.cnblogs.com/iat14/p/12289995.html