s1=ss_1=ss1=s,显然是最优的,因为答案不会更坏。
s2s_2s2 取前缀答案不会更劣。
不如s∣(1101),s∣(0101)s|(1101),s|(0101)s∣(1101),s∣(0101) 比s∣(101)s|(101)s∣(101)好。
因此枚举前缀。
因此我们只需找到第一个0的位置即可。
注意到数据随机,所以前303030位都为111的概率为1230\dfrac{1}{2^{30}}2301很小。所以枚举前30位即可。
时间复杂度:O(30n)O(30n)O(30n)
#include
using namespace std;
int n;
string s;
int main() {cin >> n >> s;string an = s;for(int i = 1; i < 30; i++) {string t = s;for(int j = i; j < n; j++) t[j] |= s[j - i];if(an < t) an = t;}int st = 0;while(st < n - 1 && s[st] == '0') st++;cout << an.substr(st) << '\n';return 0;
}