Problem G: Array C

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 4
1 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-10
using 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
****************************************************************/

菜鸟成长记

你可能感兴趣的:(ACM,STL)