poj1065-贪心法

来源:互联网 发布:悟空理财 知乎 编辑:程序博客网 时间:2024/04/30 19:51

题意解读:可以理解成给出一堆区间,把这些区间最少分成x堆,每一堆都要求l和w非递减

解法一:

按l和w从小到大排序,每次找到一个未标记的就遍历它后面的元素,如果能和它放一堆,就标记,不能就跳过直到n。

类似代码:按w排

#include <iostream>#include <cstdio>#include <cstring>#include <cctype>#include <algorithm>#include <queue>#include <vector>#include <map>#include <set>#include <cmath>#include <sstream>using namespace std;const int maxn = 20000 + 10;const int INF = 0x3f3f3f3f;const int mod = 1e9 + 7;typedef long long ll;struct P{  int l,w;  bool operator < (const P& p) const {    return  l < p.l || (l == p.l && w < p.w);  }}no[5002];int main(){    int t, n;    scanf("%d", &t);    while (t--) {        scanf("%d", &n);        for (int i=0; i<n;i ++) {            scanf("%d%d", &no[i].l, &no[i].w);        }        sort(no, no+n);        int ans = 0, c[n], used[n+1];         memset(used,0,sizeof used);        for (int i=0; i<n;i++)  {c[i] = no[i].w;}         for (int i=0; i<n;i++) {                int tt = c[i];            if (!used[i] ) {                for (int j=i+1; j<n; j++) {                if (c[j] >= tt && !used[j]) { tt = c[j]; used[j] = 1;}                }                ans++;            }         }         printf("%d\n", ans);    }    return 0;}

解法二:

先排w,再排l。依次遍历,从已经存起来的数里面找到比之小的,如果没有,就另存一个。

代码:


#include <iostream>#include <cstdio>#include <cstring>#include <cctype>#include <algorithm>#include <queue>#include <vector>#include <map>#include <set>#include <cmath>#include <sstream>using namespace std;const int maxn = 20000 + 10;const int INF = 0x3f3f3f3f;const int mod = 1e9 + 7;typedef long long ll;struct P{  int l,w;  bool operator < (const P& p) const {    return  w < p.w || (w == p.w && l < p.l);  }}no[5002];int main(){    int t, n;    scanf("%d", &t);    while (t--) {        scanf("%d", &n);        for (int i=0; i<n;i ++) {            scanf("%d%d", &no[i].l, &no[i].w);        }        sort(no, no+n);        int ans = 0, c[n];         memset(c,0,sizeof c);         for (int i=0; i<n;i++) {                int ok= 0;                for (int j=0; j<ans; j++ ){                    if (no[i].l >= c[j]) {                        c[j] = no[i].l;                        ok = 1; break;                    }                }                if (!ok ) c[ans++] = no[i].l;         }         printf("%d\n", ans);    }    return 0;}



解法三:DP

先排l,再排w。 

#include <iostream>#include <cstdio>#include <cstring>#include <cctype>#include <algorithm>#include <queue>#include <vector>#include <map>#include <set>#include <cmath>#include <sstream>#include <climits>using namespace std;const int maxn = 20000 + 10;const int INF = INT_MAX;const int mod = 1e9 + 7;typedef long long ll;struct P{  int l,w;  bool operator < (const P& p) const {    return  l < p.l || (l == p.l&& w < p.w);  }}no[5002];int main(){    int t, n;    scanf("%d", &t);    while (t--) {        scanf("%d", &n);        for (int i=0; i<n;i ++) {            scanf("%d%d", &no[i].l, &no[i].w);        }        sort(no, no+n);        int ans = 0, d[n+1];         memset(d,0,sizeof d);         for (int i=0; i<n;i++) {                d[i] = 1;                for (int j=0; j<i; j++ ){                    if ( no[j].w > no[i].w)                        d[i] = max(d[i], d[j]+1);                }                ans = max(d[i], ans);         }         printf("%d\n", ans);    }    return 0;}




0 0
原创粉丝点击