Gym-101623H High Score 思维

本文分享了一个巧妙的算法竞赛策略,通过调整数值分配,逐步提升最小值以最大化目标函数。介绍了两种实现方法,一种是通过循环调整数值达到最优解,另一种是通过暴力枚举小范围内的值来寻找最大值。策略在特定条件下有效,避免了不必要的计算,提高了效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大佬队友过的。。感觉思维很巧妙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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值