大佬队友过的。。感觉思维很巧妙Orz
思路是先把d全给最大的,再一点一点提高最小值。最后有个23333的break,是因为:这个循环中,v的结果基本上是先往上一段,然后就往下了,在顶上可能会抖一抖,所以写这么一个足够大的数,不然会TLE(大佬原话Orz)
附上AC代码:
#include <cstdio>
#include <algorithm>
#include<iostream>
using namespace std;
int main()
{
int n;
scanf("%d", &n);
while (n--)
{
long long a[3], d;
scanf("%lld%lld%lld%lld", a, a + 1, a + 2, &d);
sort(a, a + 3);
a[2] += d; //先全给最大的
long long maxv = a[0] * 7 + a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
//cout<<"ma="<<maxv<<endl;
while (d)
{
if (a[0] != a[1]) //逐步增加最小值
{
--d;
++a[0];
--a[2];
}
else //a[0]=a[1]
{
if (a[2] - a[1] >= 3 && d >= 2) //如果不满3,a[0]加后比a[2]大了
{
++a[0];
++a[1];
a[2] -= 2;
d -= 2;
}
else
break;
}
//cout<<" a[0]="<<a[0]<<" a[1]="<<a[1]<<" a[2]="<<a[2]<<endl;
long long t = a[0] * 7 + a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
//cout<<"d="<<d<<" t="<<t<<" ma="<<maxv<<endl;
if (t > maxv) maxv = t;
else if (maxv - t > 23333) //“剪枝”
break;
}
printf("%lld\n", maxv);
}
return 0;
}
后来网上搜一下发现可以暴力。。。因为平方增长较快,枚举较小的两个增加了多少,这个值不会太大。附上大佬博客Orz:https://blog.youkuaiyun.com/wxh010910/article/details/80980981
附上大佬博客中的代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll calc(int a, int b, int c) {
return (ll)a * a + (ll)b * b + (ll)c * c + 7ll * min(a, min(b, c));
}
int main() {
#ifdef wxh010910
freopen("input.txt", "r", stdin);
#endif
int T;
scanf("%d", &T);
while (T--) {
int a, b, c, d;
scanf("%d %d %d %d", &a, &b, &c, &d);
ll answer = 0;
for (int i = 0; i <= d && i <= 100; ++i) {
for (int j = 0; i + j <= d && j <= 100; ++j) {
int k = d - i - j;
answer = max(answer, calc(a + i, b + j, c + k));
answer = max(answer, calc(a + i, b + k, c + j));
answer = max(answer, calc(a + k, b + i, c + j));
}
}
printf("%lld\n", answer);
}
return 0;
}