2017NWERC High Score---思维题

做题过程:

分析了这道题的数据1e9,肯定要找到什么规律,于是就从理论上算了一下,在只有一张wild卡时,不可能加在中间牌上

加在最大值上:max^2+2max+1+mid^2+min^2+7min

加在最小值上:max^2+mid^2+min^2+2min+1+7min+7

max-min>7/2时,2max+1>2min+1+7,即此时加在最大值上最优,否则加在最小值上。

当wild数大于1时,同样有次结论。

所以重点分析max-min<7/2的情况,但是训练的时候没有分析出来。test通过最多的一次是所有的都加在最大值上算一次,所有的都加在最小的上算一次,然后取大的,wa在了30才想到加在最小的上后,最小的可能不再是最小的。

正确思路:

  1. 一种是:wild数大的时候,全部都加在最大牌数上最大,当wild数较小的时候,暴力所有的情况。即将整数d划分为3个非负整数再加在max,mid,min上。
  2. 另一种是我的思路的延续或者是升华,不过他是从最终结果开始推的,我觉得这种想法很值得学习。在max-min<7/2时直接暴力最终的情况。此时源max+mid+min+dmax+mid+min+d的值s可以算出来,然后将s分为最大值-最小值小于等于3的3个数,且满足这三个数都大于等于原来的数(如果是我绝对不会想到这一点)。大佬秀

交了后思路2时间31ms,思路1时间171ms,这就是思维的力量吧orz。

结论:

  1. 怼不出来规律就适当地暴力啊
  2. 从最终结果出发考虑问题
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
long long a[3],d;
LL b[3];
LL calc(LL a,LL b,LL c)
{
    return a*a+b*b+c*c+7*min(min(b,c),a);
}
LL solve()
{
    LL ans=0;
    LL s=a[0]+a[1]+a[2]+d;
    sort(a,a+3);
    for(int i=0;i<=3;++i)
        for(int j=0;j<=3;++j)
    {
        if(s-i-j>=0&&(s-i-j)%3==0)
        {
            b[0]=(s-i-j)/3;
            b[1]=b[0]+i;
            b[2]=b[0]+j;
 
        sort(b,b+3);
        if(b[0]>=a[0]&&b[1]>=a[1]&&b[2]>=a[2])
           ans=max(calc(b[0],b[1],b[2]),ans);
        }
    }
   return ans;

}
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        cin>>a[0]>>a[1]>>a[2]>>d;
        sort(a,a+3);
        cout<<max(solve(),calc(a[2]+d,a[1],a[0]))<<endl;
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值