[Method summary] greedy


Greedy algorithm is the current status of each guarantee optimal algorithm (local optimization) strategy election decisions. Therefore, when using a greedy need to ensure the optimal overall solution can be derived from the local optimum solution.
Greedy algorithm using the usual need to demonstrate, the following several common methods of proof:

Item 1. o exchange:

In either situation, the changes will affect the position of any element to change the current situation. The method NOIP had involved.
Sort of situation elements may provide evidence for the greedy strategy.

2. Zoom range:

Expand local optima optimal range will not affect the overall situation.

3. reductio ad absurdum, induction:

Like literally. (='Ω `=)

example:

1. P2887 [USACO07NOV] Sunscreen Sunscreen

Analysis:
The cows each according to minSPF descending order, and to find the maximum SPF sunscreen to the cow with (within reason). If two bottles of sunscreen x, y can be used, wherein spf [x]> spf [y ]. So for the next cow, there are x, y can be used, with only y, and x, y do not use these three cases. Obviously, we will lower spf sunscreen to the back of a cow will be better.
code show as below:

#include<bits/stdc++.h>
#define N 5000
using namespace std;
struct node{
    int l,r;
    bool operator <(const node &other)const{
        return l>other.l;
    }
}c[N];
struct temp{
    int num,power;
    bool operator <(const temp &other)const{
        return power>other.power;
    }
}s[N];
int n,m,ans;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&c[i].l,&c[i].r);
    for(int i=1;i<=m;i++)
        scanf("%d%d",&s[i].power,&s[i].num);
    sort(c+1,c+n+1);
    sort(s+1,s+1+m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            if(s[j].power>=c[i].l&&s[j].power<=c[i].r&&s[j].num){
                s[j].num--;ans+=1;break;
            }
        }
    printf("%d",ans);
    return 0;
}

2. P2859 [USACO06FEB] book stalls Stall Reservations

Analysis:
ordered by time of milking cows start, if a cow and the time coincides with the milking a cow next time, then create a new bullpen.
code show as below:

#include<bits/stdc++.h>
#define N 50010
using namespace std;
int n,num=1;
struct node{
    int l,r,id,vis;
    bool operator <(const node &other)const{
        return l<other.l;
    }
}c[N];
inline int cmp(node x,node y){
    return x.id<y.id;
}
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&c[i].l,&c[i].r);
        c[i].id=i;
    }
    sort(c+1,c+n+1);
    q.push(make_pair(c[1].r,1));
    c[1].vis=1;
    for(int i=2;i<=n;i++){
        int stop=q.top().first;
        int snum=q.top().second;
        if(c[i].l>stop){
            q.pop();q.push(make_pair(c[i].r,snum));
            c[i].vis=snum;
        }
        else{
            num++;
            c[i].vis=num;
            q.push(make_pair(c[i].r,num));
        }
    }
    printf("%d\n",num);
    sort(c+1,c+1+n,cmp);
    for(int i=1;i<=n;i++)
        printf("%d\n",c[i].vis);
    return 0;
}

3. P1080 Kings game

Analysis:
solving the key to this problem lies in how to make the minimum number of sort to get the most gold coins obtained minister.
We can use the exchange of items ortho derived, provided two adjacent minister \ (X \) , \ (. 1 + X \) , we calculate the maximum value after the two switching positions and minister before switching position. Obtained following persimmon:
\ [max \ left (\ FRAC {. 1} {B [I]}, \ FRAC {A [I]} {B [I +. 1]} \ right) \] \ [max \ left (\ frac {1} {B [i
+ 1]}, \ frac {A [i + 1]} {B [i]} \ right) \] At this time, both sides simultaneously by \ (B [i] * B [i + 1] \) , can be obtained:
\ [max \ left (B [I + 1], A [I] * B [I] \ right) \]
\ [max (B [I], A [I + 1] * B [i + 1])
\] comparison may be obtained, when (A [i] * B [ i] \ leq A [i + 1] * B [i + 1] \) \ when the sequence better.
Code as follows: (precision, do not write 60 minutes only)

#include<bits/stdc++.h>
#pragma GCC O(2)
#define N 10100
#define INF 0x7f7f7f7f
#define ll long long
using namespace std;
int n,L,R;
int ans[N<<1],sum[N<<1],add[N<<1];
struct node{
    int l,r;
    ll key;
    bool friend operator < (node x,node y){
        return x.key<y.key;
    }
}p[N];
inline void modify(){
    for(int i=add[0];i>=0;i--)
        sum[i]=add[i];
}
inline int compare(){
    if(sum[0]>add[0]) return 0;
    if(sum[0]<add[0]) return 1;
    for(int i=add[0];i>=1;i--){
        if(add[i]>sum[i]) return 1;
        if(add[i]<sum[i]) return 0;
    }
}
inline void multiply(int num){
    memset(add,0,sizeof(add));
    for(int i=1;i<=ans[0];i++){
        ans[i]=ans[i]*num;
        add[i+1]+=ans[i]/10;
        ans[i]%=10;
    }
    for(int i=1;i<=ans[0]+5;i++){
        ans[i]+=add[i];
        if(ans[i]>=10){
            add[i+1]+=ans[i]/10;
            ans[i]%=10;
        }
        if(ans[i]) ans[0]=max(ans[0],i);
    }
}
inline void divid(int num){
    memset(add,0,sizeof(add));
    int ext=0;
    for(int i=ans[0];i>=1;i--){
        ext*=10;
        ext+=ans[i];
        add[i]=ext/num;
        if(add[0]==0&&add[i]) add[0]=i;
        ext%=num;
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<=n;i++){
        scanf("%d%d",&p[i].l,&p[i].r);
        p[i].key=p[i].l*p[i].r;
    }
    sort(p+1,p+n+1);
    ans[0]=ans[1]=1;
    for(int i=1;i<=n;i++){
        multiply(p[i-1].l);
        divid(p[i].r);
        if(compare()) modify();
    }
    for(int i=sum[0];i>=1;i--)
        printf("%d",sum[i]);
    return 0;
}

4. P1417 cooking program

Analysis:
This is the question and a question on essentially the same, are used as proof of o-item exchange, but the derivation of solving the problem simpler. If this problem remove the array b, then it belongs to the classical linear Dp problem. Sequence between the elements to be solved, may wish to set two ingredients as \ (X, Y \) , and therefore into the formula \ ((ai-t × bi ) \) can be obtained:
wherein \ (P \) previously done End time ingredients.
\ [A [X] - (P + C [X]) * B [X] + A [Y] - (P + C [X] + C [Y]) * B [Y] \]
\ [A [ y] - (p + c [
y]) * b [y] + a [x] - (p + c [y] + c [x]) * b [x] \] after simplifying readily available: \ [ c [x] * b [y
] <c [y] * b [x] \] so long as the ingredients in accordance with this priority ordering, then ordering can guarantee the correctness of the answer.
code show as below:

#include<bits/stdc++.h>
#define N 100010
#define int long long
using namespace std;
struct node{
    int a,b,c;
}p[N];
inline int cmp(node x,node y){
    return x.c*y.b<y.c*x.b;
}
int f[N],t,n;
signed main()
{
    scanf("%d%d",&t,&n);
    for(int i=1;i<=n;i++) scanf("%d",&p[i].a);
    for(int i=1;i<=n;i++) scanf("%d",&p[i].b);
    for(int i=1;i<=n;i++) scanf("%d",&p[i].c);
    sort(p+1,p+n+1,cmp);
    for(int i=1;i<=n;i++)
        for(int j=t;j>=p[i].c;j--){
            f[j]=max(f[j],f[j-p[i].c]+p[i].a-j*p[i].b);
        }
    int ans=0;
    for(int i=1;i<=t;i++) ans=max(ans,f[i]);
    printf("%d",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/cyanigence-oi/p/11756470.html