A:给你n个数,求由交替出现的两个数组成的子串的最大长度
先离散化,dp[i][j]表示当前以i结尾,下一个需要j的最大长度
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define pause cout << " press ansy key to continue...", cin >> chh
#define file_r(x) freopen(x, "r", stdin)
#define file_w(x) freopen(x, "w", stdout)
#define lowbit(x) ((x) & (-x))
#define repit(i, c) for (__typeof__((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define rep(i, n) for (int i = 0; i < (n); i++)
#define repd(i, n) for (int i = (n - 1); i >= 0; i--)
#define FOR(i, n, m) for (int i = (n); i <= (m); i++)
#define FORD(i, n, m) for (int i = (n); i >= (m); i--)
#define mem(a, x) memset(a, x, sizeof(a))
#define pb push_back
#define X first
#define Y second
#define mp make_pair
#define sqr(r) ((r) * (r))
#define dis(x1, y1, x2, y2) (((x1) - (x2)) * ((x1) - (x2)) + ((y1) - (y2)) * ((y1) - (y2)))
#define debug1(x) cout << #x" = " << x << endl
#define debug2(x, y) cout << #x" = " << x << " " << #y" = " << y << endl
#define debug3(x, y, z) cout << #x" = " << x << " " << #y" = " << y << " " << #z" = " << z << endl
#define debug4(x, y, z, w) cout << #x" = " << x << " " << #y" = " << y << " " << #z" = " << z << " " << #w" = " << w << endl
using namespace std;
int chh;
typedef vector<int> vi;
typedef set<int> si;
typedef map<int, int> mii;
typedef pair<int, int> pii;
typedef long long LL;
const int N = 4005;
int n, e;
int dp[N][N];
int a[N], b[N];
int main() {
int u, ans;
while (~scanf("%d", &n)) {
FOR (i, 1, n) {
scanf("%d", &a[i]);
b[i] = a[i];
}
if (n <= 2) {
printf("%d\n", n);
continue;
}
sort(b + 1, b + n + 1);
e = unique(b + 1, b + n + 1) - b;
FOR (i, 1, n) a[i] = lower_bound(b + 1, b + e, a[i]) - b;
memset(dp, -1, sizeof(dp));
dp[a[1]][e + 1] = 1;
FOR (i, 2, n) {
u = a[i];
FOR (j, 1, e) {
if (dp[j][u] != -1) dp[u][j] = max(dp[u][j], dp[j][u] + 1);
if (dp[j][e + 1] != -1) {
dp[u][j] = max(dp[u][j], 2);
}
}
dp[u][e + 1] = 1;
}
ans = 2;
FOR (i, 1, e) FOR (j, 1, e) ans = max(ans, dp[i][j]);
printf("%d\n", ans);
}
return 0;
}
B:在n * n的地图中给你一个点,每次可以向四个方向扩展,问最少扩展多少次后,
遍历的点大于等于c
二分枚举答案
int n, x, y, c;
LL doIt(int l, int u, int s, int x, int y) {
int h = max(u, x - (s - y + l));
LL ans = (LL)(x - h + 1) * (y - l + 1);
if (h - 1 >= u) ans += (LL)(u + 2 * y - 2 * l - h + 1) * (h - u) / 2;
return ans;
}
LL cal(int s) {
int h;
int l = max(1, y - s), r = min(n, y + s);
int u = max(1, x - s), d = min(n, x + s);
LL ans = 0;
ans += doIt(l, u, s, x, y);
ans += doIt(y - (r - y), u, s, x, y);
ans += doIt(l, x - (d - x), s, x, y);
ans += doIt(y - (r - y), x - (d - x), s, x, y);
ans -= r - l + 1 + d - u + 1 + 1;
return ans;
}
int main() {
int s, t, mid;
LL tol;
while (~scanf("%d %d %d %d", &n, &x, &y, &c)) {
if (c == 1) {
puts("0");
continue;
}
s = 1, t = 1000000000;
while (s != t) {
mid = (s + t) >> 1;
tol = cal(mid);
if (tol >= c) t = mid;
else s = mid + 1;
}
printf("%d\n", s);
}
return 0;
}