题意:每个物品有两个属性:长和宽(长宽不可互换)。如果一个物品的长和宽均大于另一个物品,则这个物品可以罩住另一个物品,用这种罩住物品的方法将物品分组,一组之内的物品可以一个罩住一个的全部罩起来。问最少分成几组?

分析:通常这种问题是问物品最多的一组有多少个,这个问题则稍有不同。有人说要用到Dilworth定理,个人认为没什么关系。我们的做法是将物品先按照长从小到大排序。还有一个数组,用来存储当前每个分组的罩在最外层的长和宽,开始该数组为空。然后从小到大每次取出所有长度相等的物品,扣在当前的分组数组中的物品上,更新数组中存储的长宽值。这样长度相等的一起扣,在判断能不能扣的上的时候就不需要考虑长度了,之前扣好的都是长度小于当前物品的。在扣的过程中要注意发挥每个物品的最大能力,即让每个物品扣住刚好比它小一点点的物品。因为假设如果物品X不去扣比它小一点的那个物品A,而去扣比它小很多的那个物品B。而另一个物品Y,本来只能扣B不能扣A,又因为B已经被X扣了,Y只能单成一组,造成组数增加。在实际操作中是先拿当前长度的那个宽度最大的,发挥其最大作用,然后宽度次大的……为了程序实现起来简便,我们可以直接将所有物品按长度升序,宽度降序来排序,这样每次取出一个物品加入到分组中,就相当与我们刚才的操作了。

#include <cstdio>
#include <algorithm>
using namespace std; #define MAX_DOLL_NUM 20004 struct Doll
{
int width, height;
}doll[MAX_DOLL_NUM], chain[MAX_DOLL_NUM]; int doll_num;
int chain_cnt; bool operator < (const Doll &a, const Doll &b)
{
if (a.width == b.width)
return a.height > b.height;
return a.width < b.width;
} void input()
{
scanf("%d", &doll_num);
for (int i = ; i < doll_num; i++)
scanf("%d%d", &doll[i].width, &doll[i].height);
} bool fit(Doll a, Doll b)
{
return a.width > b.width && a.height > b.height;
} void work()
{
chain_cnt = ;
for (int i = ; i < doll_num; i++)
{
bool fitted = false;
for (int j = ; j < chain_cnt; j++)
if (fit(doll[i], chain[j]))
{
fitted = true;
chain[j] = doll[i];
//printf("%d %d\n", i, j);
//printf("%d %d %d %d\n", doll[i].width, doll[i].height, chain[i].width, chain[i].height);
break;
}
if (!fitted)
{
//printf("%d %d\n", doll[i].width, doll[i].height);
chain[chain_cnt++] = doll[i];
}
}
} int main()
{
int t;
scanf("%d", &t);
while (t--)
{
input();
sort(doll, doll + doll_num);
work();
printf("%d\n", chain_cnt);
}
return ;
}

poj3636的更多相关文章

  1. POJ1065Wooden Sticks[DP LIS]

    Wooden Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 21902   Accepted: 9353 De ...

  2. POJ3636Nested Dolls[DP LIS]

    Nested Dolls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8323   Accepted: 2262 Desc ...

  3. ACM学习大纲

    1 推荐题库 •http://ace.delos.com/usaco/ 美国的OI 题库,如果是刚入门的新手,可以尝试先把它刷通,能够学到几乎全部的基础算法极其优化,全部的题解及标程还有题目翻译可以b ...

  4. ACM训练大纲

    1. 算法总结及推荐题目 1.1 C++ STL • STL容器: set, map, vector, priority_queue, queue, stack, deque, bitset• STL ...

  5. ACM学习大纲(转)

    1 推荐题库 •http://ace.delos.com/usaco/ 美国的OI 题库,如果是刚入门的新手,可以尝试先把它刷通,能够学到几乎全部的基础算法极其优化,全部的题解及标程还有题目翻译可以b ...

随机推荐

  1. java追加写入txt文件

    整理了下网上的资料,数据追加写入txt文件有三种方式,见下面代码: 方法一: public void method1() { FileWriter fw = null; try { //如果文件存在, ...

  2. SDOI2017硬币游戏

    题面链接 洛咕 sol 神题,幸好我不是SD的QAQ. 假设你们都会\(O(n^3m^3)\)的高斯消元,具体来说就是建出\(Trie\)图然后套游走的板子. 然后我们发现可以把不能匹配任何串的概率压 ...

  3. 【ARC068F】Solitaire

    Description ​ 你有一个双端队列和 \(N\) 个数字,先按 \(1\) 到 \(N\) 的顺序每次从任意一端插入当前数字,再进行 \(N\) 次操作每次可以从两端弹出,求有多少种弹出序列 ...

  4. k最近邻算法(kNN)

    from numpy import * import operator from os import listdir def classify0(inX, dataSet, labels, k): d ...

  5. mongodb 使用 robo3T 等工具添加用户之后还是 auth failed 的问题

    命令行输入 mongo use 对应的 db(需要授权的数据库),如 use admin 使用命令创建一个数据库,并赋予权限: db.createUser( { user: "xxx&quo ...

  6. ZABBIX 3.0 监控MongoDB性能【OK】

    系统环境: centos7.2 zabbix-3.4   一.原理  通过以下命令查看mongodb的状态: echo "db.serverStatus()" | mongo ad ...

  7. html概括

    --引入 什么是html? HTML(Hyper Text Markup Language)超文本标记语言. -->那么第一个问题----什么是标记语言呢? 标记语言就是让文本展示更丰富,更美观 ...

  8. ubuntu内核及系统升级

    升级之前,需要先确认ubuntu当前系统版本,使用操作: root@Dy-JXQ-ubuntu-101:~# lsb_release -a No LSB modules are available. ...

  9. python 导入自定义模块

    1. 2.

  10. Diabetic Retinopathy Winner's Interview: 1st place, Ben Graham

    Diabetic Retinopathy Winner's Interview: 1st place, Ben Graham Ben Graham finished at the top of the ...