@ljt12138
2017-06-10T09:43:30.000000Z
字数 2396
阅读 881
首先特判买一个C一个D的情况。
考虑买两个C(或D),先按照价格排个序,枚举一个位置,则另一个可行位置构成一个区间。然后用ST表区间最值即可。
#include <bits/stdc++.h>using namespace std;const int MAXN = 100005;struct ft {int b, c;friend bool operator < (const ft &a, const ft &b){ return a.c < b.c; }} coin[MAXN], dm[MAXN];int top1 = 0, top2 = 0;int max_c[MAXN], max_d[MAXN];int n, c, d;int f[MAXN][25], lg[MAXN];int max_val(int i, int j){if (i > j) return 0;int k = lg[j-i+1];return max(f[i][k], f[j-(1<<k)+1][k]);}int max_val_without(int i, int j){if (i < j) return max_val(1, i);return max(max_val(1, j-1), max_val(j+1, i));}int solve(ft a[MAXN], int top, int M){sort(a+1, a+top+1);memset(f, 0, sizeof f);for (int i = 1; i <= top; i++) f[i][0] = a[i].b;for (int j = 1; j <= 20; j++)for (int i = 1; i <= top; i++) {f[i][j] = f[i][j-1];if (i+(1<<(j-1)) <= top) f[i][j] = max(f[i][j], f[i+(1<<(j-1))][j-1]);}int Rt = top, ans = 0;for (int i = 1; i <= top; i++) {if (a[i].c > M) break;while (Rt && (a[Rt].c+a[i].c > M || Rt == i)) Rt--;if (Rt == 0) break;ans = max(ans, max_val_without(Rt, i)+a[i].b);}//cout << ans << endl;return ans;}int main(){scanf("%d %d %d", &n, &c, &d);int j = 1, t = 0;for (int i = 1; i <= n; i++) {while (j*2 <= i) j <<= 1, t++;lg[i] = t;//cout << lg[i] << " ";}//cout << endl;for (int i = 1; i <= n; i++) {int a, b; char ch;scanf("%d %d %c", &a, &b, &ch);// cout << a << " " << b << "," << c << endl;if (ch == 'C') coin[++top1].b = a, coin[top1].c = b, max_c[b] = max(max_c[b], a);else dm[++top2].b = a, dm[top2].c = b, max_d[b] = max(max_d[b], a);}max_d[0] = 0, max_c[0] = 0;for (int i = 1; i <= c; i++) max_c[i] = max(max_c[i], max_c[i-1]);for (int i = 1; i <= d; i++) max_d[i] = max(max_d[i], max_d[i-1]);// case1int ans = 0;if (max_d[d] != 0 && max_c[c] != 0)ans = max(ans, max_d[d]+max_c[c]);// case2ans = max(ans, max(solve(coin, top1, c), solve(dm, top2, d)));cout << ans << endl;return 0;}
大力爆搜..CF机子也真是快...
#include <bits/stdc++.h>using namespace std;long long a, b, h, w, n;long long ai[100005];long long dat[100005], top = 0;int tms[100005];int dfs(int nd, long long h, long long w){//cout << dat[nd] << ' ' << h << ' ' << w << endl;if ((h >= a && w >= b) ||(h >= b && w >= a)) return 0;if (nd == 0) return 2333333;long long th = 1, tw = 1;int ans = 2333333;for (int i = 0; i <= tms[dat[nd]]; i++) {tw = 1;for (int j = 0; j+i <= tms[dat[nd]]; j++) {ans = min(ans, dfs(nd-1, h*th, w*tw)+i+j);if (w*tw >= 100000) break;tw *= dat[nd];}if (h*th >= 100000) break;th *= dat[nd];}return ans;}int main(){scanf("%I64d%I64d%I64d%I64d%I64d", &a, &b, &h, &w, &n);for (int i = 1; i <= n; i++) scanf("%I64d", &ai[i]);sort(ai+1, ai+n+1);for (int i = n; i >= max(1ll, n-40); i--) {tms[ai[i]]++;if (dat[top] != ai[i])dat[++top] = ai[i];// cout << i << endl;}int ans = dfs(top, h, w);if (ans < 2333333)cout << dfs(top, h, w) << endl;else puts("-1");return 0;}