2019年ccpc女生赛重现赛题解C

2019年ccpc女生赛重现赛题解C

题目:
Function
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 0 Accepted Submission(s): 0

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


思路,m先是必须先给每个函数式分至少一个1,求出和,然后对于m剩下的数字,求出每一个加上1能增加的数字利用优先队列维护给加上1后增加最少的函数加上1,最后得出结果,学长a的这题orz,tql。

AC代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<cctype>
#include<set>
#include<stack>
#include<map>
#include<queue>
#include<vector>
#include<algorithm>

#define fi first
#define se second
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define root 1,n,1
#define PB push_back
#define MP make_pair
#define pi 3.1415926535898
#define MS(x,y) memset(x,y,sizeof(x))
#define lowbit(a)  (a&(-a))

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<LL,LL> P;
const int maxn = 1e5 + 10,modd = 1e9 + 7,inf = 0x3f3f3f3f,INF = 0x7fffffff,hmod1=0x48E2DCE7,hmod2=0x60000005;
const int dir[4][2] = {{-1,0},{0,-1},{1,0},{0,1}};
const double eps = 1e-8;

template <class T> inline void scand(T &x){char c;x=0;while((c=getchar())<'0');while(c>='0'&&c<='9')x=x*10+(c-48),c=getchar();}
inline LL min(LL a,LL b){return a < b ? a : b;}
inline LL max(LL a,LL b){return a > b ? a : b;}
inline LL gcd(LL a,LL b){ return b==0? a: gcd(b,a%b); }
inline LL exgcd(LL a,LL b,LL &x,LL &y){ LL d; (b==0? (x=1,y=0,d=a): (d=exgcd(b,a%b,y,x),y-=a/b*x)); return d; }
inline LL qpow(LL a,LL n){LL sum=1;while(n){if(n&1)sum=sum*a%modd;a=a*a%modd;n>>=1;}return sum;}
inline LL qmul(LL a,LL n){LL sum=0;while(n){if(n&1)sum=(sum+a)%modd;a=(a+a)%modd;n>>=1;}return sum;}
inline LL inv(LL a) {return qpow(a,modd-2);}
inline LL madd(LL a,LL b){return (a%modd+b%modd)%modd;}
inline LL mmul(LL a,LL b){return a%modd * b%modd;}
inline void uadd(LL &a,LL b){a = madd(a,b);}
inline void umul(LL &a,LL b){a = mmul(a,b);}

struct Node
{
  LL id,x,val;
  bool operator < (const Node &a) const{
    return val > a.val;
  }
};

LL n,m,summ,sumc,a[maxn],b[maxn],c[maxn];
priority_queue<Node> pq;


int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0);cout.tie(0);
  cin >> n >> m;
  for(int i=1;i<=n;i++)
  {
    cin >> a[i] >> b[i] >> c[i];
    summ += (a[i] + b[i] + c[i]);
    pq.push(Node{i,2,3*a[i]+b[i]});
  }
  for(int i=0;i<m-n;i++)
  {
    Node f = pq.top();pq.pop();
    summ += f.val;
    pq.push(Node{f.id,f.x+1,a[f.id]*(f.x+1)*(f.x+1)+b[f.id]*(f.x+1)-a[f.id]*(f.x)*(f.x)-b[f.id]*f.x});
  }
  cout << summ << endl;
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值