Function
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 265 Accepted Submission(s): 98
Problem Description
wls 有 n 个二次函数 Fi(x) = aix2 + bix + ci (1 ≤ i ≤ n).
现在他想在∑ni=1xi = m 且 x 为正整数的条件下求∑ni=1Fi(xi)的最小值。
请求出这个最小值。
Input
第一行两个正整数 n, m。
下面 n 行,每行三个整数 a, b, c 分别代表二次函数的二次项,一次项,常数项系数。
1 ≤ n ≤ m ≤ 100, 000
1 ≤ a ≤ 1, 000
−1, 000 ≤ b, c ≤ 1, 000
Output
一行一个整数表示答案。
Sample Input
2 3 1 1 1 2 2 2
Sample Output
13
因为所有的x都大于0,所以先给所有的x赋予一个最小的值 1 ;
通过 f(x)=a*x^2+b*x+c;
f(x+1)=a*(x+1)^2+b(x+1)+c;
可以得出增量为f(x+1)-f(x)=2*a*x+a+b;
我们使用优先队列求出增量最小的一组数据 让它的x++ 最后可以得到一个结果和它下一次的增量存入队列中
之前已经放入了 n 个1 所以还有m-n个1 我们就可以通过优先队列把 1 一个个的加上去.
最后得到最小值
#include<bits/stdc++.h>
using namespace std;
int n,m,a,b,c,ans;
struct node
{
int a,b,c,x,sum,ans;
bool operator < (const node&f) const
{
return sum>f.sum; //按增量的大小 从小到大排序
}
};
priority_queue<node> q;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a>>b>>c;
node f;
f.a=a;
f.b=b;
f.c=c;
f.x=1;
f.sum=2*f.a*f.x+f.a+f.b;//增量
f.ans=f.a*f.x*f.x+f.b*f.x+f.c;//现阶段的结果
q.push(f);
}
for(int i=1;i<=m-n;i++)
{
node f=q.top();
q.pop();//增量最小的一组数据出来
f.x++;// x++;
f.sum=2*f.a*f.x+f.a+f.b;// 增量更新
f.ans=f.a*f.x*f.x+f.b*f.x+f.c;//结果更新
q.push(f);
}
ans=0;
while(!q.empty())
{
node f=q.top();
q.pop();
ans+=f.ans;//计算结果
}
cout<<ans<<endl;
return 0;
}