ACM-贪心

在对问题求解时,总是作出在当前看来是最好的选择。也就是说,不从整体上加以考虑,它所作出的仅仅是在某种意义上的局部最优解(是否是全局最优,需要证明)。
若要用贪心算法求解某问题的整体最优解,必须首先证明贪心思想在该问题的应用结果就是最优解!!
1、从问题的某个初始解出发。
2、采用循环语句,当可以向求解目标前进一步时,就根据局部最优策略,得到一个部分解,缩小问题的范围或规模。
3、将所有部分解综合起来,得到问题的最终解。

hdoj1050
只需要找出最大相交数即可

#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;

const int N = 1000;

int main(){
    int a[N] = {0};
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        int m, mx1 = 0;
        scanf("%d",&m);
        for(int j=0;j<m;j++){
            int c, d;
            scanf("%d%d",&c,&d);
            c-=1;
            c/=2;
            d-=1;
            d/=2;
            if(c>d) swap(c, d);
            if(d>mx1) mx1 = d;
            for(int p=c;p<=d;p++){
                a[p]++;
            }}
        int mx2 = 0;
        for(int j=0;j<=mx1;j++){
            if(a[j]>mx2) mx2 = a[j];
            a[j] = 0;
        }
        printf("%d\n",mx2*10);

    }
    return 0;
}

hdoj1789

先对日期从小到大排序,如果日期相同,则扣分多的排在前面。如果相同日期内有扣分多的,则就用前面做扣分少的作业的时间来做这门作业;如果没有比他小的,就扣这门作业的分。

#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;

const int N = 1005;
struct node{
    int s, t;
    bool f;
}work[N];
int cmp(node a, node b){
    if(a.t!=b.t) return a.t<b.t;
    return a.s>b.s;
}

int main(){
    int a[N] = {0};
    int n;
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&work[i].t);
            work[i].f = true;
        }
        for(int i=0;i<n;i++)
            scanf("%d",&work[i].s);
        sort(work,work+n,cmp);

        int ans = 0;
        int k = 1;
        for(int i=0;i<n;i++){
            if(work[i].t>=k){
                k++;
                continue;
            }
            int p = work[i].s;
            int pos = i;
            for(int j = 0;j<i;j++){
                if(p>work[j].s&&work[j].f){
                    p = work[j].s;
                    pos = j;
                }
            }
            ans+=p;
            work[pos].f = false;
        }
        printf("%d\n",ans);
    }
    return 0;
}

hdoj2037
按结束时间牌序。
证明:会不会有比这更个局部的,思考一下发现没有

#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;

const int N = 105;
struct node{
    int s, t;
}a[N];
int cmp(node e, node f){
    return e.t<f.t;
}

int main(){
    int n;
    while(scanf("%d",&n)&&n!=0){
        for(int i = 0;i<n;i++){
            scanf("%d%d",&a[i].s,&a[i].t);
        }
        sort(a,a+n,cmp);
        int ans = 0;
        int pos = 0;
        for(int i=0;i<n;i++){
            if(i==0) ans++;
            else{
                if(a[i].s>=a[pos].t){
                    ans++;
                    pos = i;}
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

hdoj2454
可图性判定!
1、度序列:若把图G所有顶点的度数排成一个序列S,则称S为图G的度序列。
2、序列是可图的:一个非负整数组成的有限序列如果是某个无向图的度序列,则称该序列是可图的。
Havel-Hakimi定理很容易理解:

三步走就可以了:
第一步:把序列按降序排序。
第二步:删除第一个数x。
第三步:从头开始,数x个数,全部-1
不断重复上述过程直到序列出现负数=不可图,全都为0=可图

#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;

const int N = 1005;

int cmp(int e, int f){
    return e>f;
}

void fun(int* a, int n){
    for(int i=0;i<n;i++){
        a[i] = a[i+1];
    }
}

int main(){
    int T;
    int a[N] = {0};
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
        }
        bool f = true;
        do{
            sort(a, a+n, cmp);
            int t = a[0];
            fun(a, n);
            n--;
            for(int i=0;i<t;i++){
                a[i]--;
            }
            for(int i=0;i<n;i++){
                if(a[i]<0){ f = false;
                break;}
            }
        }while(n!=0);
        if(f) printf("yes\n");
        else printf("no\n");
    }
    return 0;
}

hdoj1052
先用最快马比 不行再用最慢马比 都不行 就送最慢马给忘得最快马

#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;

const int N = 1005;

int cmp(int e, int f){
    return e>f;
}

int main(){
    int n;
    while(scanf("%d",&n)&&n!=0){
        int s1 = 0, s2 = 0, f1 = n-1, f2 = n-1;
        int a[N] = {0}, b[N] = {0};
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        for(int i=0;i<n;i++)
            scanf("%d",&b[i]);
        sort(a,a+n,cmp);
        sort(b,b+n,cmp);
        int ans = 0;
        while(n--){
            if(a[s1]>b[s2]){
                s1++;
                s2++;
                ans+=200;
            }
            else if(a[f1]>b[f2]){
                f1--;
                f2--;
                ans+=200;
            }
            else if(a[f1]==b[s2]){
                s2++, f1--;
            }
            else{
                s2++, f1--;
                ans-=200;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

sort总结:
头文件:#include
sort(首地址, 尾地址+1, [cmp函数])
第三个参数不写,默认递增

一个综合示范:


bool cmp1(student x, student y)
{ 	if( fabs(x.score - y.score) > 0.00001 ) 
        return x.score > y.score;
	if(x.age != y.age) return x.age < y.age;
	return strcmp(x.name,y.name) < 0 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值