zjnu(1299)——零件分组(LIS变形)

来源:互联网 发布:编程工具与编程 编辑:程序博客网 时间:2024/05/26 09:55
零件分组(Stick)-动态规划-中高级

Case Time Limit:1000MSTime Limit: 3000MS Memory Limit: 65536KTotal Submissions: 62 Accepted: 21

Description

某工厂生产一批棍状零件,每个零件都有一定的长度(Li)和重量(Wi)。现在为了加工需要,要将它们分成若干组,使每一组的零件都能排成一个长度和重量都不下降

Input

第一行为一个整数N(N<=1000),表示零件的个数。第二行有N对正整数,每对正整数表示这些零件的长度和重量,长度和重量均不超过10000。

Output

仅一行,即最少分成的组数。

Sample Input

58 4 3 8 2 3 9 7 3 5

Sample Output

2

思路:

刚开始看到这题的时候感觉和导弹拦截那道题的第二问很像。

但是这道题和导弹那道题的差距是,导弹那道题的导弹顺序是固定的,所以我们分组的时候也只能从前到后进行分组。

但是这里我们可以对他们的顺序进行改变后再进行分组。

所以首先我先对零件的长度进行从小到大的排序,因为我们要求的是一个LIS,这是第一个约束条件,然后我们就像导弹的第二问那样,进行分组。分组的时候要注意当有多种情况成立时,我们要选择那个w较大的那个,因为我们尽可能的要让w小的去匹配小的嘛。然后就能够求出需要几组了。

导弹那道题:导弹拦截问题 (举一反三!!)

#include<cstdio>#include<cstring>#include<map>#include<set>#include<cmath>#include<algorithm>#include<vector>#include<queue>#include<iostream>using namespace std;typedef __int64 ll;typedef unsigned __int64 ULL;#define inf 99999999#define maxn 1010int sys[maxn];struct node{    int l,w;}a[maxn];bool cmp(node a,node b){    if(a.l!=b.l) return a.l<b.l;    else return a.w<b.w;}int main(){    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++){        scanf("%d%d",&a[i].l,&a[i].w);    }    sort(a+1,a+1+n,cmp);    int tail=1;    sys[tail]=a[1].w;    for(int i=2;i<=n;i++){        int lmin=-1,tx=0;        for(int j=1;j<=tail;j++){            if(sys[j]<=a[i].w){                if(sys[j]>lmin){              //这里十分重要!!                    lmin=sys[j];                    tx=j;                }            }        }        if(lmin==-1) sys[++tail]=a[i].w;        else sys[tx]=a[i].w;    }    printf("%d\n",tail);    return 0;}/*51 11 22 12 23 1*/


0 0