在matlab中求零件分组的问题,零件分组 - osc_kfduktz3的个人空间 - OSCHINA - 中文开源技术交流社区...

题目描述

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

输入

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

输出

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

样例输入

5

8 4 3 8 2 3 9 7 3 5

样例输出

2

分析:首先每一组必须满足两个条件,零件的长度和重量都是不下降的。如果同时考虑这两个条件的话,会比较麻烦,所以好的思想是先简化条件。

那么我们可以先按长度从小到大排序,然后按这个顺序给零件分组。这样每一组零件的长度一定是不下降的,只用考虑重量即可。

那关于重量该怎么处理呢?首先可定的是,如果当前的零件的重量小于该组最后一个零件的重量的话,那一定不能放在这一组了,必须放到另一个合法的组(或者新成立一组)。

但如果这个零件可以放到这一组呢?是直接放吗?那可不一定,比如下图

9369a14e5ea81977b5d05336af4f4034.png

还有(6, 7) 和 (7, 5) 没有放,如果(6, 7) 放到第一组的话,那么(7, 5) 就必须新开一组了。但是最优的方法是(6, 7) 放到第二组,(7, 5) 放到第一组,这样总共就两组。

所以对于每一个零件,我们要放到重量和他最相近(但不能大于它)的零件上面,保证放完这个零件后所浪费的空间最少。(空间只是为了好说话,并不是严格意义上的空间)

具体代码的实现,因为题中说长度和重量均不超过 10000,那么就可以开一个数组记录每一组的最后一个零件的重量。然后对于每一个零件 i,从 w[i] 开始向 0 循环,若遇到一个vis[j] 被标记过,说明这有一组,且放完后浪费的空间一定最少,就 vis[j] --, vis[w[i]] ++, break,表示这一组的最后一个零件的重量变成了 w[i]。

1 #include

2 #include

3 #include

4 #include

5 #include

6 using namespacestd;7 #define rep(i, a, n) for(int i = a; i <= n; ++i)

8 #define per(i, n, a) for(int i = n; i >= a; --i)

9 typedef long longll;10 const int maxn = 1e3 + 5;11 const int max_num = 1e4 + 5;12

13 structNode14 {15 intl, w;16 bool operator < (const Node& other)const

17 {18 return (l < other.l) || (l == other.l && w <=other.w);19 }20 }a[maxn];21 intn, vis[max_num];22 int ans = 0;23 intmain()24 {25 freopen("stick.in", "r", stdin);26 freopen("stick.out", "w", stdout);27 scanf("%d", &n);28 rep(i, 1, n) scanf("%d%d", &a[i].l, &a[i].w);29 sort(a + 1, a + n + 1);30 rep(i, 1, n)31 {32 per(j, a[i].w, 0)33 if(vis[j]) {vis[j]--; break;}34 vis[a[i].w]++;35 }36 rep(i, 1, max_num - 1) if(vis[i]) ans++; //数一数有多少组

37 printf("%d\n", ans);38 return 0;39 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值