Time Limit: 3 second
Memory Limit: 2 MB
【问题描述】
某工厂生产一批棍状零件,每件零件都有一定的长度(li)和重量(wi)。现在为了加工需要,要将它们分成若干组,使每一组的零件都能排成一个长度和重量都不下降(若i<j,则li<=lj,wi<=wj)的序列。请问至少要分成几组
【输入格式】
两行。第一行为一个整数(n<=1000),表示零件的个数。第二行有n对正整数,每对正整数表示这些零件的长度和重量,长度和重量均不超过10000。
【输出格式】
仅一行,即最少分成的组数。
【输入样例】
5
8 4 3 8 2 3 9 7 3 5
【输出样例】
2
【题目链接】:http://noi.qz5z.com/viewtask.asp?id=9601
【题解】
先按照重量把所有的零件升序排;(重量相同则长度要升序);
否则
l w
2 3
3 3
1 2
如果排成
L 1 3 2
W 2 3 3
显然需要2组
而
L 1 2 3
W 2 3 3
只要一组;
因为W是升序的了;
所以我们就可以不用管W了
只要考虑L了;
对于L我们要顺序操作(这样才不会破坏W的不下降性);
对于一个L;如果之前没有分过组(第一个);
则增加一个组,把它放在这个组的末尾;
如果之前有分过组,则在所有的组的末尾里面找比它小的且最大的数字x;则把这个L放在x所在的组的末尾是最好的->这样可以让那些末尾数字比较小的组得以保留以便让更小的L放在它们的末尾;
如果在所有的组里面都没有末尾数字比它小的数字,则需要新建一个组了;
以此类推就能搞出组数;
贪心原则->较大的数字放在末尾最大的且合法的数字的组后面替代它成为组的末尾数字;这样能最大化地利用每一组;尽量不搞出新的组出来;
【完整代码】
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <string>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
void rel(LL &r)
{
r = 0;
char t = getchar();
while (!isdigit(t) && t!='-') t = getchar();
LL sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
void rei(int &r)
{
r = 0;
char t = getchar();
while (!isdigit(t)&&t!='-') t = getchar();
int sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
const int MAXN = 1e3+100;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
struct abc
{
int l,r;
};
int n,l[MAXN],w[MAXN];
vector <int> zu;
abc a[MAXN];
bool cmp(abc a,abc b)
{
if (a.r==b.r)
return a.l < b.l;
else
return a.r<b.r;
}
int main()
{
//freopen("F:\\rush.txt","r",stdin);
scanf("%d",&n);
rep1(i,1,n)
scanf("%d%d",&a[i].l,&a[i].r);
sort(a+1,a+1+n,cmp);
rep1(i,1,n)
{
int len = zu.size(),pos =-1,ma=-21e8;
rep1(j,0,len-1)
if (zu[j]<=a[i].l)
if (zu[j]>ma)
{
pos = j;
ma = zu[j];
break;
}
if (pos==-1)
zu.pb(a[i].l);
else
zu[pos]=a[i].l;
}
int ans = zu.size();
cout << ans<<endl;
return 0;
}