Problem G: Array C

来源:互联网 发布:如何采集新车交易数据 编辑:程序博客网 时间:2024/04/30 07:03

Problem G: Array C

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 0  Solved: 0

Description

   Giving two integers  and  and two arrays  and  both with length , you should construct an array  also with length  which satisfied:

1.0≤CiAi(1≤in)

2.

and make the value S be minimum. The value S is defined as:

Input

   There are multiple test cases. In each test case, the first line contains two integers n(1≤n≤1000) andm(1≤m≤100000). Then two lines followed, each line contains n integers separated by spaces, indicating the array Aand B in order. You can assume that 1≤Ai≤100 and 1≤Bi≤10000 for each i from 1 to n, and there must be at least one solution for array C. The input will end by EOF.

Output

    For each test case, output the minimum value S as the answer in one line.

Sample Input

3 4 2 3 41 1 1

Sample Output

6

HINT

    In the sample, you can construct an array [1,1,2](of course [1,2,1] and [2,1,1] are also correct), and  is 6.

解题思路:给你一个a数组和一个b数组,让你选一个c数组,使得其满足题目描述中的几个条件

首先因为c数组的每个元素可以选择的范围都不相同,且c数组的所有元素之和还得大于等于m,如果开始值随便选的话并不能保证满足条件

所以我们可以从最大值开始考虑,即令Ci=Ai,这时前两个条件是必定满足的,但此时得到的是最大的S,即Smax


那我们要做的是将Ci减小,当我们将Ci减小为Ci-1,那S减少了多少呢?


由上述可知,要想使S尽可能小,我们要做的就是使△S尽可能大

所以我们可以用一个优先队列,按照(2C-1)*B从大到小排列,每次将队首元素进行处理,直到c数组所有元素之和等于m时结束,这是我们得到的S即为Smin,当然在处理过程中,当某一项Ci=0之后就不能再放进队列了,因为Ci的取值最小为0

/*Sherlock and Watson and Adler*/#pragma comment(linker, "/STACK:1024000000,1024000000")#include<stdio.h>#include<string.h>#include<stdlib.h>#include<queue>#include<stack>#include<math.h>#include<vector>#include<map>#include<set>#include<cmath>#include<complex>#include<string>#include<algorithm>#include<iostream>#define exp 1e-10using namespace std;const int N = 1005;const int M = 40;const int inf = 100000000;const int mod = 2009;struct node{    int c,b;    bool operator < (const node &a) const        {              return (2*c-1)*b<(2*a.c-1)*a.b;//最大值优先           }     node(){}    node(int c0,int b0):c(c0),b(b0){}};int a[N],b[N];priority_queue<node> q;int main(){    int n,i;    long long ans,m,k;    node u;    while(~scanf("%d%lld",&n,&m))    {        while(!q.empty())            q.pop();        for(i=1;i<=n;i++)            scanf("%d",&a[i]);        for(k=ans=0,i=1;i<=n;i++)        {            scanf("%d",&b[i]);            ans+=a[i]*a[i]*b[i];            q.push(node(a[i],b[i]));            k+=a[i];        }        while(k>m)        {            u=q.top();            q.pop();            ans-=(2*u.c-1)*u.b;            if(u.c-1>0)                q.push(node(u.c-1,u.b));            k--;        }        printf("%lld\n",ans);    }    return 0;} /**************************************************************    Problem: 18    Language: C++    Result: Accepted    Time:34 ms    Memory:1520 kb****************************************************************/

菜鸟成长记

0 0