给定一个长度为n的数列和一个整数k,求两个长度不小于k的连续子序列,分别使他们的二进制或运算值和二进制与运算值最大。
对于问题一,很显然就是将所有元素或起来
但是问题二鄙人就不太会了(这是一道贪心题),我写了一个0pts 的码,求助大佬帮我讲讲思路(
Code
#include <bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int N = 1e6 + 10;
int read() {
int sum = 0, f = 1;
char c = getchar();
while (!isdigit(c)) {
if (c == '-')
f = -1;
c = getchar();
}
while (isdigit(c)) {
sum = (sum << 3) + (sum << 1) + (c ^ 48);
c = getchar();
}
return sum * f;
}
int n, k;
int a[N];
struct node {
int f = 0, num = 0;
} dp[N];
int ans1, ans2;
int main() {
n = read(), k = read();
for (int i = 1; i <= n; i++) {
a[i] = read(), ans1 |= a[i];
if ((dp[i - 1].f & a[i]) >= dp[i - 1].f) {
// cout<<dp[i-1].f<<" "<<a[i]<<" "<<(dp[i-1].f&a[i])<<endl;
if (i == 1) {
dp[i].f = a[i];
dp[i].num = 1;
} else {
dp[i].f = dp[i - 1].f & a[i];
dp[i].num = dp[i - 1].num + 1;
}
} else {
dp[i].f = a[i];
dp[i].num = 1;
}
}
// cout<<dp[4].num<<endl;
for (int i = 1; i <= n; i++) {
if (dp[i].f > ans2 && dp[i].num >= k) {
ans2 = dp[i].f;
}
}
printf("%d %d\n", ans1, ans2);
return 0;
}
样例一:
6 3
1 1 1 0 0 0 输出:1 1
样例二:
6 3
1 1 0 1 0 0 输出:1 0
样例三:
6 3
11 8 2 1 3 9输出:11 1
真的谢谢了!!