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 }
心之所动 且就随缘去吧