Greedy Law _1 2016.5.16

Source: Internet
Author: User

so-called " Greedy Algorithm " refers to the following:


when solving a problem, always make a now it seems to be the best The Choice

In other words, not considering the whole, it makes only the local optimal solution in a sense (whether it is the global optimal, need to prove)


Special Note:

To solve the whole optimal solution of a problem with greedy algorithm, we must first prove that the application result of greedy thought in this problem is the optimal solution!!


Greedy the algorithm is not able to get the overall optimal solution for all problems

The key is the choice of greedy strategy, the greedy strategy of choice must have no effect

That the previous procedure in a State does not affect the future state, only the current state


The proof of greedy algorithm

The correctness of the greedy algorithm, must have the strict significance proof, the general use is the inductive method, or is the disprove method

However, in the program design competition, as long as the program works correctly, the strict meaning of the algorithm proved not necessary
So it can be said that there is enough self-confidence, there is no need to prove
But sometimes it's not so sure, it's good to just prove it in the head.




51Nod Greedy Starter Tutorial _ Perfect string

John thinks that the perfect degree of a string is equal to the perfection of all the letters in it.

The perfect degree of each letter can be assigned by you, different letters of the perfect degree, respectively, corresponding to an integer between 1-26

John doesn't care about the letter case. (That is, the letters F and F) are of the same degree of perfection

Given a string, output its maximum possible degree of perfection

For example: Dad, you can assign 26 to d,25 to assign to a so that the entire string is 77 perfect.


Analysis: By the sort inequalities, the letters with the most occurrences should obviously give 26

So this topic turns out to count the number of occurrences of each letter, and then assigns the weights from highest to lowest in number of occurrences, from large to small.

This is the simplest greedy thought.


Input
Enter a string s (s of length <= 10000), s in which there are no characters other than letters.

Output
You assign 1-26 to different letters, so that the perfect degree of the string s is the maximum, the output of this perfect degree.

Input example
Dad

Output example
77


This code, which I wrote a long time ago, was not known to have the useful library functions

#include <iostream> #include <cstdio>using namespace std;typedef struct _scord {char s; int n;}    _scord;void Sort (int a[],int n) {int i,j,t;                For (i=0, i<n-1; i++) {for (j=i+1; j<n; J + +) {if (A[i] < a[j]) {t = A[i];                A[i] = A[j];            A[J] = t;    }}}}int Main () {char s[10000];    _scord scord[26];    int num[26];    int i,j;    int sum = 0;    int s_num = 0;    int flag = 0;        while (cin>>s) {scord[0].s = s[0];        SCORD[0].N = 1; for (i=1,s_num=0; s[i]!= ' + '; i++) {for (j=0,flag=0; j<s_num+1; J + +) {if (S[i]==scord[j].s | | s[i]==scord[j].s-32 | |                    S[I]==SCORD[J].S+32) {scord[j].n++;                    flag = 1;                Break                }} if (0 = = flag) {s_num++;                SCORD[S_NUM].S = S[i];            SCORD[S_NUM].N = 1; }        } for (i=0; i<s_num+1; i++) {num[i] = SCORD[I].N;        } Sort (num, (s_num+1));        for (i=0,sum=0; i<s_num+1; i++) {sum + = num[i] * (26-i);    } cout<<sum<<endl; } return 0;}

#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include < algorithm> #include <queue> #include <vector> #include <stack> #include <map>using namespace Std;typedef Long long ll;typedef unsigned long long ull;typedef unsigned int uint;const int INF = 0x7fffffff;const int max n = 1e4 + 10;char s[maxn];int vis[30];int cmp_num (const void* A, const void* b); int main () {#ifdef __air_h freopen ("in.t    XT "," R ", stdin); #endif//__air_h gets (S);    STRLWR (S);    int len = strlen (S);    memset (Vis, 0, sizeof (VIS));        for (int i = 0; i < len; ++i) {int t = s[i]-' a ';    ++VIS[T];    } qsort (Vis, N, sizeof (vis[0)), cmp_num);    int ans = 0;    for (int i = 0, j = n; i < && vis[i]! = 0; ++i,--j) {ans + vis[i] * j;    } printf ("%d\n", ans); return 0;} int Cmp_num (const void* A, const void* b) {return (* (int*) B-* (int*) a) > 0 1:-1;}





51Nod Greedy Starter Tutorial _ canoe problem

n individuals, known to each body weight, canoe load-bearing fixed, each canoe up to two people, can sit a person or two people

It is clear that the total weight does not exceed the load of the canoe, assuming that each person weighs less than the canoe load, how many canoes do I need at least?

Analysis:

An obvious strategy is to sort by the weight of people

Extreme greed strategy, the heaviest person to get on board-if the heaviest person and the lightest weight sum does not exceed the load of the ship, then they both occupy a boat

Otherwise (because assuming the heaviest person's weight does not exceed the load of the ship), the heaviest person occupies a single boat

Turn into a (n–1) or (n–2) question.

The point is that this greedy strategy is right.

We can prove that the optimal solution can also be changed into this strategy

(1) Assuming that the heaviest person and the lightest person weigh and exceed the weight of the ship, then the optimal solution is obviously also the heaviest person to occupy a single boat, so the optimal and greedy strategy is the same in this case
(2) Assuming the heaviest person and the lightest person's weight and not exceeding the ship's load

(2.1) If the best solution, the heaviest person occupies a boat alone, you can put the lightest person also put up, so that the optimal solution of the number of ships do not increase

If the lightest person occupies a boat, we can put the heaviest man up, and the best solution is not to increase the number of ships.

(2.2) If the heaviest person in the optimal solution x and X ' Occupy a ship (x, X '), while the lightest man y and y ' occupy a boat (Y, y ')
Let's change (x, y) (x ', y ')

(x, Y) clearly does not exceed the weight of the ship-because we assume so. Key look (x ', y ')

X ' + y ' <= x ' + x because (x ', x) is not overweight, so (x ', Y ') is also legal. So change, the optimal number of ships will not increase

So we can prove that if we could put the heaviest man and the lightest man on a boat, it wouldn't affect the optimal solution.

By applying this strategy over and over again, you can reduce the size of N to (n–1) or (n–2) individuals to solve this problem


Input
The first line contains two positive integers n (0<n<=10000) and M (0<m<=2000000000), representing the number of people and the weight of the canoe
The next n lines, one positive integer per line, represent the weight of each person. Weigh no more than 1000000000, and each person's weight does not exceed M

Output
An integer line indicates the minimum number of canoes required.

Input example
3 6
1
2
3

Output example
2


#include <iostream>using namespace std;void Sort (int a[],int n) {int i,j,t;                For (i=0, i<n-1; i++) {for (j=i+1; j<n; J + +) {if (A[i] > A[j]) {t = A[i];                A[i] = A[j];            A[J] = t;    }}}}int Main () {int n,m;    int i,j,k;    int num = 0;    int weight[10000] = {0};    int f_num,s_num;        while (Cin>>n>>m) {for (i=0; i<n; i++) {cin>>weight[i];        } Sort (Weight,i);        F_num = 0;        S_num = i-1;                for (j=0,num=0; j<i-1; J + +) {if (Weight[f_num]+weight[s_num] <= m) {num++;                f_num++;            s_num--;                } else {num++;            s_num--;            } if (1 = = F_num-s_num) {break;                } if (F_num = = s_num) {num++;            Break }} cout<<num<< Endl; } return 0;}





51Nod Greedy Starter Tutorial _ Event Scheduling issues

There are several activities, the first start time and end time is [Si,fi], there is only one classroom, the activities can not overlap between the maximum number of activities to arrange?

Analysis: We just want to improve the utilization rate of classrooms and arrange activities as much as possible.
Consider several greedy strategies that are easy to think about:

(1) Start the earliest activities first, the goal is to end the activities as soon as possible, let out the classroom
However, this is obviously not possible, as the earliest activities may be long and affect our subsequent activities.

For example, activity start and end times are [0, 100), [up], [2, 3], [3, 4], [4,5], schedule [0,100] After this activity, other activities cannot be scheduled, but the optimal solution is to arrange 4 activities except for it

(2) Short activities first, the goal is to empty the classroom as far as possible

But it is not difficult to construct the following counter example: [0,5] [5,10] [3, 7), here [3,7] the shortest, but if we arrange [3,7], the other two can not be arranged

But the optimal solution is obviously to arrange the other two, and give up [3,7], it can be seen that this greedy strategy is not possible


(3) The least conflicting activities are preferred, since the activities above are planned to reduce conflict, so if we prioritize the activities with the least conflict?

At least (1) and (2), this strategy is effective.

Is that right? Try this example:

[0,2] [2,4] [4,6] [6,8]
[1,3] [1,3] [1,3] [3,5] [5,7] [5,7] [5,7]

Take a look at [0,2] and 3 active conflicts-3 [1,3]

[2,4) and 4 active conflicts 3 [1,3] and one [3,5]
[4,6] and also 4 active conflicts 3 [5,7] and one [3,5]
[6,8] and 3 active collisions--3 [5,7]

Each of the following [1,3] and [5,7] conflicts with 5 activities
and [3,5] only with two active conflicts--[2,4) and [4,6]

That should be arranged according to our strategy [3,5], but once [3,5] is selected, we can only schedule up to 3 activities
But obviously the first line of 4 activities can be arranged, so this strategy is also wrong


(4) Seemingly the most wrong strategy-the sooner the end time the activity first

This strategy is effective and we can prove

Assuming that the optimal solution in OPT is arranged for m activities, we also sort these activities by the end time from small to large, apparently without conflict

Assuming the order is sorted, these activities are a (1), A (2), a (3) .... am

Assuming that according to our greedy strategy, the selected activities are naturally sorted by the end time, and are also non-conflicting, these activities are B (1), B (2) ... b (n)

The point is, suppose a (1) = B (1), a (2) = B (2) .... A (k) = B (k), but a (k+1)! = B (k+1), answer a few questions:

(1) B (k+1) will appear in a (k+2), A (k+3), .... A (m)?
No.

Because the end time of B (k+1) is the earliest, i.e. F (b (k+1)) <= F (A (k+1)), and A (k+2), A (k+3), .... A (m) Start and end times are after F (A (k+1)), so B (k+1) is not in it

(2) B (k+1) and a (1), A (2), .... A (k) conflict?
Does not conflict because a (1), A (2), .... A (k) is B (1), B (2), .... b (k)

(3) B (k+1) and A (k+2), A (k+3), .... A (m) conflict?
does not conflict because F (b (k+1)) <= F (A (k+1)), and A (k+2), A (k+3), .... A (m) Start time is after F (A (k+1)), and after F (b (k+1)).

So we can change a (k+1) to B (k+1), so that the solution to the best and the greedy we get is a lot of the same

After a substitution, we can completely replace the optimal solution with the solution obtained by our greedy strategy.

This proves the optimality of this greedy strategy.


Input
Line 1th: 1 number N, number of segments (2 <= n <= 10000)
2-n + 1 lines: 2 numbers per line, beginning and end of line segments ( -10^9 <= s,e <= 10^9)

Output
Outputs the maximum number of segments that can be selected.

Input example
3
1 5
2 3
6 S

Output example
2


#include <iostream>using namespace std;void Sort (int a[],int b[],int n) {    int i,j,t;    For (i=0, i<n-1; i++) {for        (j=i+1; j<n; J + +) {            if (A[i] > A[j]) {                t = a[i];                A[i] = a[j];                A[J] = t;                t = b[i];                B[i] = b[j];                B[J] = t;}}}    int main () {    int n;    int i,j;    int left[10000] = {0};    int right[10000] = {0};    int right_val = 0;    int num = 1;    while (Cin>>n) {for        (i=0; i<n; i++) {            cin>>left[i]>>right[i];        }        Sort (right,left,i);        for (J=1,num=1,right_val=right[0]; j<i; J + +) {            if (Left[j] >= right_val) {                num++;                Right_val = Right[j];            }        }        cout<<num<<endl;    }    return 0;}

#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include < algorithm> #include <queue> #include <vector> #include <stack>using namespace Std;typedef long Long Ll;typedef unsigned long long ull;typedef unsigned int uint;const int INF = 0x3f3f3f3f;const int MAXN = 10000 + 10;struct Node {int S, E;}; Node node[maxn];int cmp_num (const void* A, const void* b), int main () {#ifdef __air_h freopen ("In.txt", "R", stdin), #endi    f//__air_h int n; while (scanf ("%d", &n)! = EOF) {for (int i = 0; i < n; ++i) {scanf ("%d%d", &node[i].s, &amp        ; node[i].e);        } qsort (node, n, sizeof (node[0]), cmp_num);        int Count = 1;        int now_e = NODE[0].E;                for (int i = 1; i < n; ++i) {if (Node[i].s >= now_e) {now_e = NODE[I].E;            ++count;    }} printf ("%d\n", Count); } return 0;} int Cmp_num (const void* A, CONST void* b) {node* x = (node*) A;    Node* y = (node*) b; Return (X->e-y->e) > 0? 1:-1;}


HDU 2037 this summer holiday does not AC

#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include < algorithm> #include <queue> #include <vector> #include <stack>using namespace Std;typedef long Long Ll;typedef unsigned long long ull;typedef unsigned int uint;const int INF = 0x3f3f3f3f;const int MAXN = + 10;struct No de {int S, E;}; Node node[maxn];int cmp_num (const void* A, const void* b), int main () {#ifdef __air_h freopen ("In.txt", "R", stdin), #endi    f//__air_h int n; while (scanf ("%d", &n)! = EOF && n! = 0) {for (int i = 0; i < n; ++i) {scanf ("%d%d", &A        MP;NODE[I].S, &AMP;NODE[I].E);        } qsort (node, n, sizeof (node[0]), cmp_num);        int Count = 1;        int now_e = NODE[0].E;                for (int i = 1; i < n; ++i) {if (Node[i].s >= now_e) {now_e = NODE[I].E;            ++count;    }} printf ("%d\n", Count); } return 0;} int Cmp_num (cOnst void* A, const void* b) {node* x = (node*) A;    Node* y = (node*) b; Return (X->e-y->e) > 0? 1:-1;}


51Nod Greedy Starter Tutorial _ event Scheduling question two

There are a number of activities, the start and end time is [SI,FI], the activities can not overlap between the activities are scheduled to complete, at least a few classrooms required?

Analysis:

Can you arrange as many activities as possible for each classroom according to the solution of one problem

That is, by the end of the order, and then greedy choice of non-conflict activities, after arranging a classroom, the remaining activities to allocate a classroom, continue to greedy choice ...

Counter example: a:[1,2) b:[1,4) c:[5,6) d:[3,7)

have been sorted by end time, we will choose
Classroom 1: A C
Classroom 2:b
Classroom 3:d
3 classrooms Required
But if we change the arrangement, we can arrange ad in one classroom, and BC in another classroom, two classrooms is enough

So the previous greedy strategy couldn't solve the problem.
What to do?

The previous strategy is to use a classroom to find all the activities it can arrange, that is, to use the classroom to find activities, we can use activities to find the classroom?

Strategy:

Prioritize activities by start time, or add a classroom if a conflict is in order
In a nutshell, the strategy is that we sort the activities in a small order from the start time to the big one.

Assuming that the K classrooms are currently assigned (obviously K is initially equal to 0), for the current activity
(1) If it can be arranged in one of the K classrooms, arrange it in one of the classrooms, K unchanged
(2) Otherwise it conflicts with the activities in each classroom, then add a classroom, arrange this activity

Is this strategy optimal?

Let's imagine the process of K adding 1:

Because we are sorted by the start time, it means that there are activities in K classrooms that are not over at the beginning of the current consideration of the activity.

(because if the activity of a classroom is over, we can arrange the activity to enter that classroom without conflict, thus not adding k)

This means that at the beginning of the event, the activity is currently under consideration, with (k + 1) activities in progress, and (k + 1) activities at the same time.

No matter how we arrange our classrooms, we need at least (k + 1) classrooms

Because each classroom cannot carry out two activities at the same time. And our strategy exactly needs (k + 1) classrooms, so it's the best

This strategy also tells us that if you consider this issue from the "macro" on the timeline

Consider the number of simultaneous activities at each point in time, as the thickness of this point in time

(Think of the activity start and end time as line segments, then how many segments of each point of time will cover it, can be simply understood as "thickness")

We need at least the maximum thickness of so many classrooms-because then there is a maximum thickness so many activities simultaneously

And our greedy strategy just gives us a plan to arrange all the activities with the maximum thickness of the classrooms.

If we only need the number of classrooms, we can sort all the start time and end time, meet the start time to add 1 thickness, the end time to reduce the thickness of 1

Obviously the initial and final end of the thickness is 0, in the course of a series of thickness changes, peak (maximum) is the maximum number of simultaneous activities, but also we need at least the number of classrooms

Input
The first line, a positive integer n (n <= 10000), represents the number of activities.
The second line to the (n + 1) row contains n start time and end time.
The start time is strictly less than the end time, and the time is a non-negative integer, less than 1000000000

Output
A row contains an integer that represents the minimum number of classrooms.

Input example
3
1 2
3 4
2 9

Output example
2


#include <iostream>using namespace std;void Sort (int a[],int b[],int n) {int i,j,t;                For (i=0, i<n-1; i++) {for (j=i+1; j<n; J + +) {if (A[i] > A[j]) {t = A[i];                A[i] = A[j];                A[J] = t;                t = B[i];                B[i] = B[j];            B[J] = t;    }}}}int Main () {int n;    int i,j,k;    int left[10000] = {0};    int right[10000] = {0};    int class[10000] = {0};    int num = 0;    int flag = 0;        while (Cin>>n) {for (i=0; i<n; i++) {cin>>left[i]>>right[i];        } Sort (Left,right,i);        Class[0] = right[0];                     for (j=1,num=0; j<i; J + +) {for (k=0,flag=0; k<num+1; k++) {if (Left[j] >= class[k]) {                    CLASS[K] = Right[j];                    flag = 1;                Break     }} if (0 = = flag) {num++;           Class[num] = Right[j];    }} cout<<num+1<<endl; } return 0;}

#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include < algorithm> #include <queue> #include <vector> #include <stack>using namespace Std;typedef long Long Ll;typedef unsigned long long ull;typedef unsigned int uint;const int INF = 0x3f3f3f3f;const int MAXN = 10000 + 10;struct Node {int S, E;}; Node Node[maxn];int class[maxn];bool cmp_num (const Node A, const node B), int main () {#ifdef __air_h freopen ("In.txt", "R    ", stdin); #endif//__air_h int n;    scanf ("%d", &n);    for (int i = 0; i < n; ++i) {scanf ("%d%d", &node[i].s, &AMP;NODE[I].E);    } Sort (node, node+n, Cmp_num);    int Count = 0;        for (int i = 0; i < n; ++i) {bool flag = false;                for (int j = 0; j < Count; ++j) {if (Node[i].s >= class[j]) {flag = true;                CLASS[J] = NODE[I].E;            Break }} if (!flag) {Class[count] = NODE[I].E;        ++count;    }} printf ("%d\n", Count); return 0;} BOOL Cmp_num (const Node A, const node B) {return (A.S < B.S);}












Greedy Law _1 2016.5.16

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.