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; }