[Greedy / binary] Exercise Week4 A + B + C problem

A.ddl fear (greedy)

The meaning of problems

There are n ([1,1000]) job, each about a corresponding DDL, if the job is not done before the DDL, the score will be deducted (the same consumption of each job unit time)
required is minimal the number of points deducted

Sample

Sample input:
the number of data sets representative of the first row of a T digital
number representative of the number n of the first row of each set of sample job of
ddl next row n digital ai represents the i th job
next line represents the n digital bi score of the i-th job
. 3
. 3
. 3. 3. 3
10. 5. 1
. 3
. 1. 3. 1
. 6. 3 2
. 7
. 1. 4. 3. 4 2. 6. 4
. 3. 1 2. 4. 5. 6. 7
sample output:
a set of data output represents the least one answer ans minus the score on a separate line
0
. 3
. 5


Thinking

1. Each task ddl descending order of size, i.e., in front of the large ddl

2. The time t is initialized to the maximum ddl (t large then useless, because there is no need to do the job) traversing forwardly from the time t

3. at each time t, the from k (initialized to 1) task to traverse the array of n, in which the score values onto the stack until the large root task [I] t is not equal to ddl and large root stack pop top of the stack Representative t-- element and the value of the time t is completed q.top () task (note for each loop also increase since k is k for each iteration, because the start of the task vector index)

4. processing t finish in the heap after summing all the elements, namely a minimum deduction of points


to sum up

1. Since each job only 1 unit of time, scheduling impact on other operations is very small, so we have to prioritize high score for jobs

2. For a job, we expect it to be completed as late as possible, so you can put in front of the front work ddl give time, then reverse traversal t

3 because of the need to maintain the maximum, it is considered large root heap optimize performance


Code

#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#define MAXN 1010
using namespace std;
struct task
{
    int score;
    int ddl;
    bool operator <(const task & x ) const{
        if(ddl!=x.ddl)  return ddl>x.ddl;
        else return score>x.score;
    }
}a[MAXN];
bool cmp(task a,task b)
{
    if(a.ddl!=b.ddl)    return a.ddl>b.ddl;
}
int main()
{
    int T,n;
    cin>>T;
    while(T--)
    {
        int ans=0;
        priority_queue< int > q;
        cin>>n;
        for(int i=1;i<=n;i++)   cin>>a[i].ddl;
        for(int i=1;i<=n;i++)   cin>>a[i].score;
        sort(a+1,a+n+1,cmp);
        int t=a[1].ddl;//我们只需要考虑时间[1,t]内
        int k=1;
        while(t!=0)
        {
            for(int i=k;i<=n&&a[i].ddl==t;i++,k++)  q.push(a[i].score);
            if(!q.empty())  q.pop();//每个时刻内完成一个任务(如果有任务)
            t--;
        }
        while(!q.empty())
        {
            ans+=q.top();//剩下的任务是没被做完的
            q.pop();
        }
        cout<<ans<<endl;
    }

    return 0;
}

B. four columns (two points)

The meaning of problems

Four containing n ([1,4000]) abcd series elements, depicting a number from the number of columns 4, ask how many such emulated and number 4 is 0 (if a number of columns in the same size elements, as two different elements of the process)

Sample

Sample input:
a first line of a number n
next n lines each number represents the four BI CI DI AI (AI, BI, CI, DI <= 2 ^ 28)
. 6
-45 22 is 42 is -16
-41 -27 56 is 30
-36 77 -37 53 is
-36 30 -46 -75
26 is -38 -10 62 is
-32 -6 -54 45
sample output:
Total outputs a digital representation program
5


Thinking

1. enumeration of all combinations of a and b, and it is stored in all possible vector
2. The vector in ascending order
3. All combinations enumerated c and d, with d and c to find the inverse of the binary vector . I.e., first find the smallest index, the maximum index and then to find and add 1 subtract


to sum up

1.n = 4000 data representing we only use or n ^ 2 n ^ 2 log n programs and data size of 2 ^ 28 is such that we can not use the bucket sort method that is simple and easy to write, so we can only save into a container and then to find out.

2. find elements in an ordered sequence, binary search algorithm is undoubtedly the best ^ ^


Code

#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<vector>
#define MAXN 5010
using namespace std;
int a[MAXN],b[MAXN],c[MAXN],d[MAXN];
int n,ans;
vector<int> v;
int check(int x)
{
    int l=0,r=v.size()-1,mid,min_index=-1,max_index=-1;
    while(l<=r)//找最小下标
    {
        mid=(l+r)/2;
        if(v[mid]>x)    r=mid-1;
        else if(v[mid]<x)   l=mid+1;
        else if(v[mid]==x)  {r=mid-1;min_index=mid;}
    }
    l=0;r=v.size()-1;
    while(l<=r)//找最大下标
    {
        mid=(l+r)/2;
        if(v[mid]>x)    r=mid-1;
        else if(v[mid]<x)   l=mid+1;
        else if(v[mid]==x)  {l=mid+1;max_index=mid;}
    }
    if(min_index==-1)   return 0;
    else return max_index-min_index+1;
}


int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)   cin>>a[i]>>b[i]>>c[i]>>d[i];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)   v.push_back(a[i]+b[j]);

    sort(v.begin(),v.end());

    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)   ans+=check(-c[i]-d[j]);
    
    cout<<ans<<endl;
    system("pause");
    return 0;
}

C.TT mystery gift

The meaning of problems

Given array cat [i] a number N, and generate a new array ans [i] with the array. It is defined as the new array for any i, j and i = j, are ans [] = abs (cat [i] - cat [j])!, 1 <= i <j <= N. This new array. Determine the median, then the median is the sort (len + 1) / 2 corresponding to the position number, '/' is a rounding.


Sample

Sample input:
multiple sets of input that each input N, the number of expressed N, after the input of a sequence of length N CAT, CAT [I] <= 1E9,. 3 <= n-<= 1E5
. 4
. 1 2. 4. 3
. 3
1102
sample output:
output new array ans median
. 1
. 8


Thinking

1. We can first ordered sequence for ai, aj we predetermined j> i so put apart to an absolute value of number

2. Since for a new series of numbers, he will change over the order of increasing the value of increases , so there may dichotomous answer

3. therefore, we can first half of the answer, assuming that the answer is mid, order a new sequence is then calculated mid, if less than the median interval to look for the right, otherwise in Looking to the right of the interval, while recording the update ans ( Note that the order of the median is not necessarily exactly n position (n-1) / 2 may contain as a repeating sequence element such as 1,122,232 of = 5! = 2 but 3 is required so it equals the median normalized to> inside *)

4. answer a query by the order of the time that is in accordance with conventional binary aj-ai <= x i then we can enumerate bipartite Looking aj <= ai + x with the maximum index i and summing subtracting it is the current order of answers


to sum up

N 1. 1E5 is present questions, if violent by enumerating all, combinations of i j, and find their median sort, the time complexity O (n ^ 2logn ^ 2) levels is clearly inappropriate of

2. therefore, this title uses a first-half answer another common dichotomy determine the order of the current answer method greatly reduces the procedure time complexity of

3-half answer this approach has a very wide range of applications, but we may not be able to see the Road the question can not be used to do half the answer, so the key is to see whether there is half the answer to do

Code

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#define MAXN 200010
int cat[MAXN];
int n;
using namespace std;
int func(int x,int i)//该函数用于计算有多少个 cat[j] <=x 即 j的最大值 
{
    int l=1,r=n,mid,ans=-1;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(cat[mid]<=x)  {ans=mid;l=mid+1;}
        else if(cat[mid]>x) r=mid-1;
    }
    if(ans==-1) return 0;
    else return ans-i;
}
int main()
{
    // freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    while(scanf("%d", &n) != EOF)
    {
        for(int i=1;i<=n;i++)  scanf("%d",&cat[i]);
        sort(cat+1,cat+n+1);//为了拆除绝对值号 约定让 aj-ai 其中j>=i        
        //基本思路为二分答案 假设p是答案 计算 aj-ai<=p 的所有序偶 即 aj<=ai+p
        int l=0,r=cat[n]-cat[1],mid;//中位数的取值在 0 到 最大减最小之间
        //中位数为排序之后 (len+1)/2位置的数字 故 <=zws 的数有(len+1)/2个
        int len=n*(n-1)/2,ans=0;
        int zws_rank=(len+1)/2;//长度为 1+2+3+···+n-1 = n(n-1)/2
        while(l<=r)//此处为二分答案的框架  计算 mid 排在第几位
        {
            mid=(l+r)>>1;
            int sum=0;
            for(int i=1;i<=n;i++)    sum+=func(cat[i]+mid,i);
            if(sum>=zws_rank)    {ans=mid;r=mid-1;}
            else if(sum<zws_rank)   l=mid+1;
        }
        cout<<ans<<endl;
    }
    return 0;
}
Published 12 original articles · won praise 0 · Views 506

Guess you like

Origin blog.csdn.net/linshen_jianhai/article/details/104850877