Function
题解
首先暴力肯定是不行的,考虑怎么优化一下,因为当前这个方程有两个变量 x 和 g(x),所以优先考虑固定一个变量就只剩下一个变量了,而x 属于 [1, 1e6], 因此g(x) 最大也就是99999 这个数转换过去变成54,所以考虑枚举每一个g(x) 然后当g(x) 固定以后,原来式就变成了
f(x)=(ag(x)+b) x ^ 2+(cg^2(x)+d g(x)) x
这种形式的一个二次函数,每一个g(x)的x的取值一定是一个坐标轴上递增的
我们设x ^ 2 的系数为A, x 的系数为 B 进一步就变成了
f(x)=Ax ^ 2 + B x
分类来看:
1. 当A = 0 f(x) 是一个正比例函数,答案一定在左右端点,判断一下就行
2. 当 A < 0 f(x) 开口向下 最小值也一定在两端,判断一下就行
3. 当 A > 0 f(x) 开口向上 最小值应该是极值点,而求极值可以用三分,找一下即可
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <set>
#include <queue>
#include <vector>
#include <map>
#include <unordered_map>
#include <cmath>
#include <stack>
#include <iomanip>
#include <deque>
#include <sstream>
#define x first
#define y second
using namespace std;
typedef long double ld;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef unsigned long long ULL;
const int N = 1e5 + 10, M = 2 * N, INF = 0x3f3f3f3f, mod = 1e9 + 7;
const double eps = 1e-8;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int h[N], e[M], ne[M], w[M], idx;
void add(int a, int b, int v = 0) {
e[idx] = b, w[idx] = v, ne[idx] = h[a], h[a] = idx ++;
}
LL n, m, a, b, c, d;
LL get_g(LL x) {
LL res = 0;
while (x) {
res += x % 10;
x /= 10;
}
return res;
}
LL f(LL a, LL b, LL x) {
return a * x * x + b * x;
}
vector<LL> g[55];
//Ag + b cg^2 + dg
int main() {
ios::sync_with_stdio(false), cin.tie(0);
LL T;
for (LL i = 1; i <= 1e6; i ++ )
g[get_g(i)].push_back(i);
cin >> T;
while (T -- ) {
LL res = 1e18; // 开LL
cin >> a >> b >> c >> d >> n;
for (LL i = 1; i <= 54; i ++ )
if (g[i].size()) {
LL l = 0, r = upper_bound(g[i].begin(), g[i].end(), n) - g[i].begin() - 1; // 找大于x的第一个数
if (l > r) continue;
LL A = a * i + b, B = c * i * i + d * i;
if (A <= 0) res = min({res, f(A, B, g[i][0]), f(A, B, g[i][r])});
else {
while (l <= r) { // 三分
LL m1 = l + (r - l) / 3, m2 = r - (r - l) / 3;
if (f(A, B, g[i][m1]) > f(A, B, g[i][m2])) l = m1 + 1;
else r = m2 - 1;
}
res = min(res, f(A, B, g[i][l]));
}
}
cout << res << endl;
}
return 0;
}
// 99999
// 54
本文介绍了一种优化算法,针对给定的二次函数f(x) = ax^2 + bx + cg^2(x) + dg(x),通过枚举g(x)并利用二次函数特性,通过三分查找找到在区间[1, 1e6]内最小值的方法。博客详细讲解了如何固定g(x)后转化为一元二次函数,并根据不同情况(正比、开口方向)讨论了解题策略。
7523

被折叠的 条评论
为什么被折叠?



