一开始想的是求个导之类的,没有想过一步一步的算。每次把增量最小的++。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef long long ll;
struct node
{
int x,num;
ll sub,sum;
bool operator <(const node b)const
{
return sub>b.sub;
}
};
ll a[N],b[N],c[N];
ll fun(int i,int x)
{
return a[i]*x*x+b[i]*x+c[i];
}
priority_queue<node>que;
bool vis[N];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
while(!que.empty())
que.pop();
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
que.push({1,i,fun(i,2)-fun(i,1),fun(i,1)});
}
m-=n;
while(m>0&&m--)
{
node now=que.top();
que.pop();
que.push({now.x+1,now.num,fun(now.num,now.x+2)-fun(now.num,now.x+1),fun(now.num,now.x+1)});
}
ll ans=0;
while(!que.empty())
{
node now=que.top();//cout<<now.num<<":"<<now.x<<endl;
que.pop();
if(!vis[now.num])
{
ans+=now.sum;
vis[now.num]=1;
}
}
printf("%lld\n",ans);
}
return 0;
}