洛谷-P2198 殺螞蟻
阿新 • • 發佈:2017-11-03
mil ems true highlight char s ++ name sca pri
Solution
大致感受一下,我們就可以發現似乎激光塔一定要放在最末尾才能最大化一個激光塔給螞蟻的傷害,所以所有的激光塔我們強制全部放在最末尾.然後呢,我們需要把前面的多余空位合理安排給放射塔和激光塔,這個過程可以用DP來解決,大致就是設F[i][j] 表示前i+j格空位放置i座幹擾塔,j座放射塔給螞蟻帶來的最大傷害.沒了.
f[i][j]=max(f[i - 1][j] + g * j * b * k,f[i][j - 1] + g * (b * i + t) * k)
好,但是由於數據實在太大,所以要加上復雜的高精度,嗯,大概就是要寫高精乘高精,高精乘低精,高精減低精,高精加高精,高精加低精,高精度數大小比較等等,不過沒事,也就幾行...
#include<bits/stdc++.h> using namespace std; const int mo = 100000000, maxn = 1055; struct node{ long long w[30]; inline void operator += (long long x){ w[1] += x; int i = 1; while (w[i] >= mo) w[i] -= mo, ++ w[++i]; if (i > w[0]) w[0] = i; } }; inline node operator + (node a, node b){ for (int i = 1; i <= b.w[0]; ++i) a.w[i] += b.w[i]; a.w[0] = max(a.w[0], b.w[0]); for (int i = 1; i <= a.w[0]; ++i) if (a.w[i] >= mo) a.w[i] -= mo, ++ a.w[i + 1]; if (a.w[a.w[0] + 1]) ++ a.w[0]; return a; } inline node operator * (node a, node b){ node c; memset(c.w, 0, sizeof(c.w)); for (int i = 1; i <= a.w[0]; ++i) for (int j = 1; j <= b.w[0]; ++j) c.w[i + j - 1] += a.w[i] * b.w[j]; c.w[0] = a.w[0] + b.w[0] - 1; for (int i = 1; i <= c.w[0]; ++i) if (c.w[i] >= mo) c.w[i + 1] += c.w[i] / mo, c.w[i] %= mo; while (c.w[c.w[0] + 1]) ++ c.w[0]; return c; } inline node operator * (node a, long long x){ for (int i = 1; i <= a.w[0]; ++i) a.w[i] *= x; for (int i = 1; i <= a.w[0]; ++i) if (a.w[i] >= mo) a.w[i + 1] += a.w[i]/mo, a.w[i] %= mo; if (a.w[a.w[0] + 1]) ++ a.w[0]; return a; } inline node operator - (node a, node b){ for (int i = 1; i <= b.w[0]; ++i) a.w[i] -= b.w[i]; for (int i = 1; i <= a.w[0]; ++i) if (a.w[i] < 0) a.w[i] += mo, -- a.w[i + 1]; while (a.w[0] > 0 && !a.w[a.w[0]]) -- a.w[0]; return a; } inline bool operator < (node a, node b){ if (a.w[0] != b.w[0]) return a.w[0] < b.w[0]; for (int i = a.w[0]; i; --i) if (a.w[i] != b.w[i]) return a.w[i] < b.w[i]; return false; } inline void read(node &a){ char s[300]; memset(a.w, 0, sizeof(a.w)); scanf("%s", s); int m = strlen(s); int x,j,i; for (x = 0, j = 1, i = m - 1; ~i; --i, j *= 10){ if (j == mo) j = 1, a.w[++a.w[0]] = x, x = 0; x += (s[i] - ‘0‘) * j; } if (x) a.w[++ a.w[0]] = x; if (!a.w[0]) a.w[0] = 1; } inline void print(node a){ printf("%lld", a.w[a.w[0]]); for (int i = a.w[0] - 1; i > 0; --i){ for (int j = 10; j < mo; j *= 10) if (a.w[i] < j) putchar(‘0‘); printf("%lld", a.w[i]); } puts(""); } long long n; node r, g, b, t; node f[maxn][maxn], ans; inline node max(node a, node b){ return a < b ? b : a; } int main(){ scanf("%lld", &n); read(r); read(g); read(b); read(t); //return 0; for (long long i = 1; i <= n; ++i) f[0][i] = f[0][i - 1] + g * t * (n - i); for (long long i = 1; i < n; ++i) for (long long j = 1, k; k = n - i - j; ++j) f[i][j] = max(f[i - 1][j] + g * j * b * k, // b * k ?a?óá?ò?×ù?éè??toó?à3?μ?ê±??, g * j ?aj×ù·?é??tμ?é?o|. f[i][j - 1] + g * (b * i + t) * k); // ?a×ùD??óμ?·?é??t?ì3éμ?é?o|ê? g, ′?ê±????3?D?μ?ê±???a i * b + t, 12óDk??,???′ // é?o|?a g * (i * b + t) * k for (long long i = 0; i <= n; ++i) for (long long j = 0; j <= n - i; ++j) { long long k = n - i - j; if (k < 0) continue; ans = max(ans, f[i][j] + (t + b * i) * k * r); } print(ans); return 0; } /* 400 2147483647 2147483647 2147483647 1000 */
洛谷-P2198 殺螞蟻