星际网络( 数学(starstar ))
- 时限:(1s) 内存:(256M)
Descrption
- (LY) 星系有很多个星球。它们之间通过一个巨大的互联网进行通讯。随着信息时代的发展,旧的网络已经不能满足需求,于是 (LY) 星系决定建设一个新的网络。
- (LY) 星系有很多个星球,有些星球一天有几十个小时,有些星球一天只有几个小时。但每个星球的一个小时都是一样长的。因此每个星球一天的长短都不一样,这就导致了一个问题:星球上的生物都是在白天工作夜晚 休息,因此每个星球每天都有上网高峰期和低峰期,当很多星球同时达到高峰期时,网络便会变得异常拥堵,进而带来延迟。所以 (LY) 星系需要建设一个有足够大带宽的网络来避免这一问题。现在他们想知道,网络在一个小时内的最大流量是多少。
Input
- 输入数据的第一行为一个正整数 (N),表示 (LY) 星系共有 (N) 个星球。
- 接下来 (N) 行,每行描述一个星球。对于每个星球的描述,开头为两个正整数 (D,T),表示这个星球一天有 (D) 个小时,当前位于 (T) 时刻(即某一天已经过去了 (T) 小时).
- 接下来是 (D) 个正整数 (q_0,q_1……q_{D-1}),其中 (q_i) 表示第 (i) 小时到第 (i+1) 小时的流量。
Output
- 输出共一行,为一个整数 (Ans),表示一个小时内的最大流量。
Sample Input
2
4 0 1 2 3 4
2 0 3 1
Sample Output
6
Hint
- 在 (4n+3) 时刻,流量(=3+3=6) 达到最大。
- 对于 (10\%) 的数据,(N<=10);
- 对于 (20\%) 的数据,(N<=100);
- 对于 (40\%) 的数据,(N<=10000);
- 对于 (70\%) 的数据,(N<=50000);
- 对于全部的数据,(N<=100000,0<=T<D<=24,q_i<=1000000);
- 来源:
分析
- 首先观察到算法时间复杂度与 (n) 无关,因为一天的长度相同的星球都可以合并,至多 (24)个。
- 若 (A,B) 星球的小时数互质,则 (A) 星球每个时刻与 (B) 星球每个时刻均有机会重合。也就是说,若 (A) 星球的小时数与 (1sim 24) 其他数都互质,则无论其他数字如何选择,这个星球都可以取到它的最大流量。(13,17,19,23) 满足这个条件。其他数字暴力枚举到它们的最小公倍数即可。
Code
#include <bits/stdc++.h>
typedef long long LL;
const int MAX = 55440;//除了13,17,19,23外其他数的最下公倍数
int n,tmp[30];
LL ans,psum,sum[30][30];
void Calc(int D){//计算一天的最大流量
LL Max = 0;
for(int i = 1; i <= D; ++i)Max = std::max(Max,sum[D][i]);
psum += Max;
}
void Solve(){
scanf("%d",&n);
for(int i = 1; i <= n; ++i){//n个星球D相同的合并,最多就剩下24个星球
int D,T;scanf("%d%d",&D,&T);
for(int j = 1; j <= D; ++j)scanf("%d",&tmp[j]);
for(int st = T + 1,t = 1; t <= D; ++st,++t){//时刻同步,时刻从1开始
if(st > D)st -= D;//T+1(平移了一位)都对应t=1时刻,其他依次后倒
sum[D][t] += tmp[st];//合并到一起
}
}
Calc(13);Calc(17);Calc(19);Calc(23);
for(int i = 1; i <= MAX; ++i){//大于MAX的就重复的循环了
LL cursum = 0;
for(int j = 1; j <= 24; ++j){//枚举24个合并的星球
if(j == 13 || j == 17 || j == 19 || j == 23)continue;
int cur = (i - 1) % j + 1;//计算时刻
cursum += sum[j][cur];
}
ans = std::max(ans,cursum);
}
printf("%lld
",ans + psum);
}
int main(){
Solve();
return 0;
}