洛谷 CF1260A 【Heating】

题意

我们可以将原题转化为这样一个较为形象的问题:

你可以任选 c i c_i ci 个数,使得它们的和为 s u m i sum_i sumi,求一种方案使得所选的数的平方和最小。

分析

我们用一些简单的初中数学知识进行推导:

设两个数 a , b ∈ ( 0 , + ∞ ) a,b\in(0,+∞) a,b(0,+)

∵ ( a + b ) 2 = a 2 + b 2 + 2 a b , a > 0 , b > 0 ∵(a+b)^2=a^2+b^2+2ab,a>0,b>0 (a+b)2=a2+b2+2ab,a>0,b>0

∴ a 2 + b 2 < ( a + b ) 2 ∴a^2+b^2<(a+b)^2 a2+b2<(a+b)2

由此,我们可以得到本题的基本思路:使每个选择的数都尽量小(因为把一个大数拆成两个小数显然更优),也就是取平均数

然而,我们可以发现, s u m c \dfrac{sum}{c} csum 不一定是整数,这时我们可以这样做:将余数全部拆分为 1 1 1,加到其他的平均数里面。

举个例子,假设 s u m = 11 sum=11 sum=11 c = 3 c=3 c=3

我们求出平均数为 3 3 3,余数为 2 2 2

333···2

我们将 2 2 2 分为两个 1 1 1,加到 3 3 3 里面:

344

这就是最优解。

代码

#include<iostream>
#include<cstdio>
using namespace std;
int n;
int c,sum;
int a,b,ans;
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&c,&sum);
		a=sum/c;//平均数
		b=sum-a*c;//余数
		ans=a*a*(c-b)+(a+1)*(a+1)*b;
		printf("%d\n",ans);
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值