[A through study notes] Problems greedy

# LOJ10000. "1.1 cases through a 1" activity schedule

[Title] Italy

Logarithmic axis line segments, and the segments selected are most disjoint.

[Thinking]

Consider the sort of line. Due to the overall savings right boundaries as much as possible, we have the right to carry out sort key point, sequential scan all sections, if able to join the collection interval joined.

May also be considered after the end of the discrete, continuous process that began a line segment can "jump" to the nearest location from each point, then jump to the simulation.

The latter idea here is the code.

#include <bits/stdc++.h>
using namespace std;

int s[1005],t[1005],f[2005],n;

int main() {
    cin>>n;
    for(int i=1;i<=n;i++) cin>>s[i]>>t[i];
    map<int,int> mp;
    for(int i=1;i<=n;i++) {
        mp[s[i]]++;
        mp[t[i]]++;
    }
    int idx = 0;
    for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++)
        it->second = ++idx;
    for(int i=1;i<=n;i++) {
        s[i]=mp[s[i]];
        t[i]=mp[t[i]];
    }
    for(int i=1;i<=idx;i++)
        f[i]=idx+1;
    for(int i=1;i<=n;i++) {
        f[s[i]]=min(f[s[i]],t[i]);
    }
    for(int i=idx-1;i;--i)
        f[i]=min(f[i],f[i+1]);
    int pin = 1, cnt = 0;
    while(pin <= idx) {
        pin=f[pin];
        ++cnt;
    }
    cout<<cnt-1<<endl;
}

# LOJ10001. "1.1 cases through a 2" trees

[Title] Italy

Filling a sequence of length n is 01, there are h requirement, each request is described as (b, e, t), i.e. the subscript interval [b, e] at least one t 1.

[Thinking]

Obviously the difference constraints can be, but could use some greedy nature.

According to the right point in order to deal with all sort range, while maintaining the target sequence 01, if the current scanned interval does not meet the requirements, from the current range of the right point on the left to fill. This ensures that the current can be filled into a new maximum use.

The title data to a lesser extent, to maintain direct violence, complexity of O (n ^ 2).

To accelerate, maintain the 01 sequences may be considered segment tree, and the node with the overlay mark interval recording. Each time the segment tree modified by a bipartite cover border to find k, the interval [k, T] coverage. Query is easy. Complexity of O (nlogn).

Bitset maintenance or use, complexity of O (n ^ 2/64).

#include <bits/stdc++.h>
using namespace std;

struct range {
    int l,r,t;
    bool operator < (const range &b) {
        return r < b.r;
    }
} a[100005];

int n,h,b[100005],ans=0;

int main() {
    cin>>n>>h;
    for(int i=1;i<=h;i++) cin>>a[i].l>>a[i].r>>a[i].t;
    sort(a+1,a+h+1);
    for(int i=1;i<=h;i++) {
        int cnt = 0;
        for(int j=a[i].l;j<=a[i].r;j++) cnt+=b[j];
        if(cnt < a[i].t) {
            cnt = a[i].t - cnt;
            for(int j=a[i].r;j>=a[i].l && cnt>0; --j)
                if(b[j]==0)
                    b[j]=1, --cnt, ++ans;
        }
    }
    cout<<ans<<endl;
}

# LOJ10002. "3 1.1 cases through a" sprinkler

[Title] Italy

L * W rectangle has a round n, each center in the width direction of the center line, and know the position of each circle radius. Seeking a minimum number of round can cover the entire rectangle.

[Thinking]

Consider the sort of line. Due to the overall savings right boundaries as much as possible, we have the right to carry out sort key point, sequential scan all sections, if able to join the collection interval joined.

Here after discrete "jump" ideas more easily accuracy problems rather than recommended.

#include <bits/stdc++.h>
using namespace std;

int T,n;
double l,w;
double x[20005],r[20005];
double pl[20005],pr[20005];

struct Item {
    double l,r;
    bool operator < (const Item &x) {
        return l < x.l;
    }
} item[20005];

int main() {
    ios::sync_with_stdio(false);
    cin>>T;
    while(T--) {
        cin>>n;
        cin>>l>>w;
        memset(x,0,sizeof x);
        memset(r,0,sizeof r);
        memset(pl,0,sizeof pl);
        memset(pr,0,sizeof pr);
        for(int i=1;i<=n;i++) cin>>x[i]>>r[i];
        for(int i=1;i<=n;i++) {
            double tmp = pow(r[i],2)-pow(w/2.0,2);
            double del = (tmp>=0? sqrt(tmp) : 0);
            pl[i] = x[i] - del;
            pr[i] = x[i] + del;
            //cout<<pl[i]<<" ,"<<pr[i]<<endl;
            item[i].l = pl[i];
            item[i].r = pr[i];
        }
        sort(item+1,item+n+1);
        //for(int i=1;i<=n;i++) cout<<item[i].l<<" "<<item[i].r<<endl;
        double now = 0.0001, tmp = 0.00001;
        int cnt = 0;
        for(int i=1;i<=n;i++) {
            if(now < item[i].l && now < l) {
                now = tmp;
                ++cnt;//cout<<"now "<<now<<" "<<cnt<<endl;
            }
            tmp = max(tmp, item[i].r);
        }
        if(now < l) now=tmp, ++cnt;
        if(now >= l) cout<<cnt<<endl;
        else cout<<-1<<endl;
    }
}

# 10003. "4 1.1 cases through a" process of production scheduling

[Title] Italy

N-products, need to process each of a [i] at the time the machine A, B and then machining b [i] time. What makes the shortest total time required.

[Thinking]

Johnson dual-scheduling model. We can give a simplified proof.

Assuming that only two products. 1 is assumed to processing over the prior process 2, then there

a1 + max(b1,a2) + b2 < a2 + max(b2,a1) + b1

Simplification get

max(b1,a2) - a2 - b1 < max(b2,a1) - b2 - a1

Dismantled

-min (b1, a2) <-min (b2, a1)

which is

min (a1, b2) <min (a2, b1)

This result can not promote, because of the lack of transfer. We need further processing

For a, b have to discuss the size of our discovery

1) a1 <b1 and a2 <b2, then we need a1 <a2 ordering

2) a1 = b1 and a2 = b2, free

3) a1> b1 and a2> b2, then we need b2> b1 ordering

4) a1> b1 and a2 <b2, the inequality necessarily true

5) a1 <b1 and a2> b2, the inequality does not hold constant

It is easy to find a ai <bi elements will eventually appear in the front part of the sequence, and a ai> bi element will eventually appear in the rearward part of the sequence. That is, all ai> bi certain elements located behind the elements ai <bi's.

For all ai <bi elements, we will follow the ascending order ai, ai for all> element bi, bi we sorted in descending order.

So we got Johnson dual-scheduling algorithm.

We maintain two stacks, all the elements in sequence in ascending order by the insertion min (ai, bi). If ai <bi is inserted first, second or insertion. Finally, the second stack is connected to an inverted stack behind the first, the operation order of the sequence is obtained.

As the sequence of time spent calculating, can be simulated.

#include <bits/stdc++.h>
using namespace std;

int n;
struct Item {
    int a,b,id;
    bool operator < (const Item &x) {
        return min(a,b) < min(x.a,x.b);
    }
} item[100005];
vector <int> ans1,ans2;
vector <int> seq;
int ta[100005],tb[100005];

int main() {
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>item[i].a, item[i].id=i;
    for(int i=1;i<=n;i++) cin>>item[i].b;
    sort(item+1,item+n+1);
    for(int i=1;i<=n;i++) {
        if(item[i].a<=item[i].b) ans1.push_back(i);
        else ans2.push_back(i);
    }
    seq.push_back(0);
    for(int i=0;i<ans1.size();i++) seq.push_back(ans1[i]);
    for(int i=ans2.size()-1;i>=0;--i) seq.push_back(ans2[i]);
    for(int i=1;i<=n;i++) ta[seq[i]]=ta[seq[i-1]]+item[seq[i]].a;
    for(int i=1;i<=n;i++) tb[seq[i]]=max(ta[seq[i]],tb[seq[i-1]])+item[seq[i]].b;
    cout<<tb[seq[n]]<<endl;
    for(int i=0;i<ans1.size();i++) cout<<item[ans1[i]].id<<" ";
    for(int i=ans2.size()-1;i>=0;--i) cout<<item[ans2[i]].id<<(i?" ":"");
    cout<<endl;
}

 [Develop] a kind neighbor term exchange Scheduling

EXAMPLE 1 Kings game

[Title] Italy

N personal station in a row, each have a [i] and b [i]. Each score obtained all left = a [i] is the product of their ÷ b [i]

Requirements to minimize the highest score.

[Thinking]

Consider two adjacent i, j, with a j = i + 1. We left all sets i a [j] of the product to be k.

Considering adjust the order of the two men will not affect the front and back of people's scores, we just let the two men who scored high scores can be as small as possible.

If i is the front, the rear j, then max (k / b [i], (ka [i]) / b [j])

If after i, j front, the max (k / b [j], (ka [j]) / b [i])

Sufficient Conditions have to be exchanged simplify i, j is a [i] b [i]> a [j] b [j]

Example 2 Queen game

[Title] Italy

Background conditions as above. I that is obtained fraction c [i], the

i=1时,c[i]=a[i]+b[i]

i>1时,c[i] = max(c[i-1], a[1]+...+a[i]) + b[i]

Similarly, we want to minimize the highest score.

[1] Ideas

Simplification of the embodiment mimic readily min (a [i], b [j])> min (a [j], b [i]) for the exchange.

[Strict weak ordering]

For an operator <, a <satisfied by using! <Represented satisfied. If the following conditions are met, for the strict weak ordering.

1) non-reflexive i.e. x! <X

2) i.e. if the asymmetry x <y then y! <X

3) That is, if transmission of x <y, y <z then x <z

4) if no comparable transmissibility x! <Yy! <Xy! <Zz! <Y if x! <Zz! <Y

[1] on the idea of ​​reflection

It is clear that for any i, j, k, if min (ai, bj) <min (aj, bi) and min (aj, bk) <min (ak, bj) then min (ai, bk) <min (ak, bi)

But not transitive not comparable. Because here is not comparable can be seen as an equal sign, so it is easy to find counterexamples.

This means that the number of adjacent elements may appear larger than the elements of the case in front of the rear element of the exchange, which is not optimal.

In general, if a sort mode is correct, then it needs to meet strict weak ordering, and for any i <j, there min (ai, bj) <= min (aj, bi)

[2] Ideas

We observed that the idea of ​​a major error lies in not comparable on. Can we not comparable set of processing a way to get to make the best? Thus, in min (ai, bj) == when min (bi, aj), we put a little forward.

【summary】

For a class may be adjacent to such exchange by two non-strict solution becomes excellent, we can deal with exchange sort items by o. But note that meet strict weak ordering of.

# 10004. "5 1.1 cases through an" intellectual Big Surf

[Title] Italy

There are n tasks, each task takes 1 unit of time to complete each task has its ddl, you can not complete the corresponding scores will be lost. Minimize loss.

[Thinking]

Taking into account for any period of time 0 ~ t, if we must give up some, we certainly want to give those small loss.

Therefore, in accordance with the task ddl ordering, maintaining a small heap root, enumerate the current time, and add all this time ddl task. If a small number of elements is greater than the current number of the root of the heap may be accommodated (numerically equal to the time), the top of the stack will constantly pop.

#include <bits/stdc++.h>
using namespace std;

struct Item {
    int s,t;
    bool operator < (const Item &x) {
        return t < x.t;
    }
} item[100005];

int n,m;

int main() {
    ios::sync_with_stdio(false);
    cin>>m>>n;
    for(int i=1;i<=n;i++) cin>>item[i].t;
    for(int i=1;i<=n;i++) cin>>item[i].s;
    sort(item+1,item+n+1);

    priority_queue <int,vector<int>,greater<int> > q;

    for(int i=1;i<=n;i++) {
        q.push(item[i].s);
        while(q.size() > item[i].t) {
            m-=q.top();
            q.pop();
        }
    }

    cout<<m<<endl;
}

# 10005. "One through 1.1 Exercise 1" number of columns poor

[Title] Italy

Given the number n, where each operation can remove two numbers a, b, and insert a number ab + 1. Until only a number. Finally, to get the maximum number of max is the minimum min, find max-min.

[Thinking]

Consider the case of three numbers, if a <b <c, then

First operation a, b: {a, b, c} -> {ab + 1, c} -> {abc + c + 1}

First operation b, c: {a, b, c} -> ... -> {abc + a + 1}

Induction process known to the minimum number of two, the maximum value is finally obtained, whereas the minimum.

So with a large stack and a small root root can be maintained separately heap.

#include <bits/stdc++.h>
using namespace std;

int n,a[100005];
priority_queue <int,vector<int>,greater<int> > q1;
priority_queue <int,vector<int>,less<int> > q2;

int main() {
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) q1.push(a[i]), q2.push(a[i]);
    for(int i=1;i<n;i++) {
        int t=q1.top(); q1.pop();
        t*=q1.top(); q1.pop();
        q1.push(t+1);
        t=q2.top(); q2.pop();
        t*=q2.top(); q2.pop();
        q2.push(t+1);
    }
    cout<<q1.top()-q2.top()<<endl;
}

 

# 10006. "A practice through 1.1 2" series segments

[Title] Italy

Length N is a positive number of columns requires the minimum number of segments such that each segment into and not more than M.

[Thinking]

Taking into account the first paragraph must start from the beginning of the program. Scanning from the beginning, when necessary, can cut out some.

#include <bits/stdc++.h>
using namespace std;

int n,m,a[100005];

int main() {
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    int tmp = 0, ans = 1;
    for(int i=1;i<=n;i++) {
        if(tmp+a[i]<=m) {
            tmp+=a[i];
        }
        else {
            tmp=a[i];
            years ++ ; 
        } 
    } 
    Cout << age << endl; 
}

# 10007. "one through 1.1 Exercise 3" line

[Title] Italy

N-number line segment, the k selected such that there is no overlap. Seeking a maximum value k.

[Thinking]

Consider the same sort 10002. segment. Due to the overall savings right boundaries as much as possible, we have the right to carry out sort key point, sequential scan all sections, if able to join the collection interval joined.

#include <bits/stdc++.h>
using namespace std;

struct Item {
    int l,r;
    bool operator < (const Item &x) {
        return r < x.r;
    }
} item[1000005];

int n;

int main() {
    cin>>n;
    for(int i=1;i<=n;i++) cin>>item[i].l>>item[i].r;
    sort(item+1,item+n+1);
    int pos = 0, ans = 0;
    for(int i=1;i<=n;i++) {
        if(item[i].l >= pos)
            pos = item[i].r,
            ++ans;
    }
    cout<<ans<<endl;
}

# 10008. "1.1 Exercise 4 through a" Homework

With 10004.

#include <bits/stdc++.h>
using namespace std;

int n;
struct Item {
    int a,b;
    bool operator < (const Item &x) {
        return a<x.a;
    }
} item[1000005];

int main() {
    cin>>n;
    for(int i=1;i<=n;i++) cin>>item[i].a>>item[i].b;
    sort(item+1,item+n+1);
    priority_queue <int,vector<int>,greater<int> > q;
    for(int i=1;i<=n;i++) {
        q.push(item[i].b);
        while(q.size() > item[i].a) q.pop();
    }
    int ans = 0;
    while(q.size()) ans+=q.top(), q.pop();
    cout<<ans<<endl;
}

# 10009. "1.1 Exercise 5 through a" fishing

[Title] Italy

N has a lake, from i to i + 1 take the time t [i]. Each takes a longer time to Lake score f [i], the time to spend a score f [i] -d [i], to spend a f [i] -2d [i], and so on. Finally, the end of a lake can any longer. Seeking to obtain the maximum score within the given time total.

【answer】

Time range is not great, maintain a small heap root for all of the current selection, from left to right in the final enumeration which ended lake. Since the longer the time spent on the road to the right, can be used for fishing, the less time, so each time the excess elements stack pop right movements. Each to a new lake, the lake will be the root of all opt-small heap, while maintaining the total number can be.

#include <bits/stdc++.h>
using namespace std;

int n,h,f[105],d[105],t[105],tmp,ans;
priority_queue <int,vector<int>,greater<int> > q;

int main() {
    cin>>n>>h;
    for(int i=1;i<=n;i++) cin>>f[i];
    for(int i=1;i<=n;i++) cin>>d[i];
    for(int i=1;i<n;i++) cin>>t[i];
    h*=12;
    for(int i=1;i<=n&&h>0;i++) {
        for(int j=1;j<=240&&f[i]>0;++j)
            q.push(f[i]), tmp+=f[i], f[i]-=d[i];
        while(q.size()>h) tmp-=q.top(), q.pop();
        ans=max(ans,tmp);
        h-=t[i];
    }
    cout<<ans<<endl;
}

# 10010 "through a 1.1 Exercise 6" candy transfer

[Title] Italy

There are n individual ring, each person has a [i] th items. Everyone who only transmitted towards the adjacent sides, a consideration of the number of items 1. seeking all adjusted to the same total price.

[Thinking]

Note avg = sum (ai) / n, the number of each person needs to be supplemented for the ai - avg

Since the introduction of negative, we may assume that the number i as i + 1 is transmitted xi, then

avg = where - x [in] + x [i-1]

Therefore x [i] -x [i-1] = ai - avg (i> 2)

Particularly when i = 1, and avg = a1 - x1 + xn

I.e., x [1] -x [n] = a1 - avg

It is easy to find the equations on x [] again an infinite number of solutions. But we can consider solving the relative relationship between them

It might be x [1] treated as a variable, to represent other

x [2] = ai - Avg + x [1] = x [1] - (a [1] -avg)

x [3] = ai - avg + x [2] = a [2] - avg + x [1] + a [1] - avg = x [1] - (a [1] + a [2] -avg -avg)

......

We now need to find a point to all (sigma (a [1-> i]) - i * avg) and the minimum distance. Apparently the median.

#include <bits/stdc++.h>
using namespace std;

#define ll long long
ll n,a[1000005],avg,c[1000005],mid,dis;

int main() {
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) avg+=a[i];
    avg/=n;
    for(int i=1;i<=n;i++) c[i]=c[i-1]+a[i]-avg;
    sort(c+1,c+n+1);
    if(n&1) mid = c[n/2+1] * 2;
    else mid = (c[n/2] + c[n/2+1]);
    for(int i=1;i<=n;i++) dis+=abs(c[i]*2-mid);
    dis/=2;
    cout<<dis<<endl;
}

 

Guess you like

Origin www.cnblogs.com/mollnn/p/11576463.html