可以发现,购买方案是有周期的,周期个数即为购买次数。
对于固定的购买次数,我们可以贪心的求出最多存活多少天。
但是我们并不知道要购买多少次,反正是个函数最值问题,直接模拟退火!
看了题解之后,发现购买次数与答案为单峰函数关系,那么可以换成三分法了。。
贪心的话,先预处理出每次要购买的食物(因为有些食物一定不会去买的),然后在保质期内,贪心的全买这种食物即可。
/* Telekinetic Forest Guard */ #include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> using namespace std; typedef long long LL; typedef double DB; const int maxn = 205; const DB dT = 0.9; int n, tot; LL M, F, ans; struct _data { LL p, s; } food[maxn], tmp[maxn]; template <class nt> inline void read(nt &x) { bool f = 0; x = 0; char ch = getchar(); for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? 1 : 0; for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0'; if(f) x = -x; } inline bool cmp1(_data x, _data y) { return x.s != y.s ? x.s < y.s : x.p < y.p; } inline bool cmp2(_data x, _data y) { return x.p != y.p ? x.p < y.p : x.s > y.s; } inline void init() { sort(food + 1, food + 1 + n, cmp1); int cnt = 0; tmp[++cnt] = food[1]; for(int i = 2; i <= n; i++) if(food[i - 1].s != food[i].s) tmp[++cnt] = food[i]; sort(tmp + 1, tmp + 1 + cnt, cmp2); tot = 0; food[++tot] = tmp[1]; for(int i = 2; i <= cnt; i++) if(tmp[i - 1].p != tmp[i].p) food[++tot] = tmp[i]; } inline LL getans(LL x) { if(!x) return 0; LL res = 0, money = M - F * x, d = 0; for(int i = 1; i <= tot; i++) { LL amount = min(money / food[i].p / x, food[i].s - d + 1); money -= amount * x * food[i].p; d += amount; res += amount * x; if(d <= food[i].s) { amount = money / food[i].p; res += amount; return res; } } return res; } inline void Simulated_Annealing() { LL x = M / (F + food[1].p) / 2; ans = getans(x); for(DB T = M / F; T >= 1.0; T *= dT) { LL newx = x + (LL)((rand() % 2 ? -1.0 : 1.0) * (rand() % 9999 + 1) / 10000.0 * T / 2.0); if(newx <= 0) newx = (LL)((rand() % 9999 + 1) / 10000.0 * T); LL newans = getans(newx); if(newans > ans) ans = newans, x = newx; } } int main() { read(M); read(F); read(n); for(int i = 1; i <= n; i++) read(food[i].p), read(food[i].s); init(); Simulated_Annealing(); printf("%lld\n", ans); return 0; }
时间: 2024-10-25 17:54:10