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

分析:通常这种问题是问物品最多的一组有多少个,这个问题则稍有不同。有人说要用到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. BZOJ 3295 动态逆序对 | CDQ分治

    BZOJ 3295 动态逆序对 这道题和三维偏序很类似.某个元素加入后产生的贡献 = time更小.pos更小.val更大的元素个数 + time更小.pos更大.val更小的元素个数. 分别用类似C ...

  2. 【ARC075F】Mirror

    Description ​ 给定正整数\(D\),求有多少个正整数\(N\),满足\(rev(N)=N+D\). ​ 其中\(rev(N)\)表示将\(N\)的十进制表示翻转来读得到的数(翻转后忽略前 ...

  3. 【Learning】容斥原理

    PPT在这里 https://files.cnblogs.com/files/RogerDTZ/%E5%AE%B9%E6%96%A5%E5%8E%9F%E7%90%86.pdf

  4. GridView中网络图片延迟加载导致高度计算失败的问题

    在使用下拉刷新以及加载更多控件的时候,出现了列表上滚不完的现象,经过半天的分析,最后得出结论:由于图片采用了延迟加载,导致列表按照没有加载图片时候的大小进行布局,相关的加载更多控件也就傻逼了. 最终解 ...

  5. %1$s %1$d Android string (java & Android 格式化字符串)

    1$s // String%1$d // int //R.string.old:<string name="old">我今年%1$d岁了</string> ...

  6. 解题:HEOI 2012 采花

    题面 题外话:LYD说他当时看错题了,考场爆零了,然后有了作诗这道题=.= 离线处理询问,按右端点递增排序,然后对于每种花$flw[i]$,我们求一个$pre[flw[i]]$表示这种花上一次出现的位 ...

  7. bzoj 3772 :精神污染 线段树+打标记 or 主席树

    3772: 精神污染 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 315  Solved: 87[Submit][Status][Discuss] D ...

  8. 闲:测试memcpy和std::copy vector之间拷贝

    预测:底层C函数肯定比stl算法快 结果:少量数据底层快,大数据以上则stl对vector的处理可能更好 C/C++: #include <iostream> #include <v ...

  9. python pip安装--不是内部或外部命令--解决方案

    首先在 命令行中输入 python -m ensurepip 创建出pip3.exe  , 并找到pip3.exe所在的Scripts路径 使命令行在Scripts路径下 输入pip3 install ...

  10. etcd启用https服务

    目录 cfssl相关工具下载 生成etcd所需要的ssl证书 生成ca证书 生成etcd服务端证书 生成etcd客户端证书 修改etcd集群配置文件 重启etcd集群 验证集群健康情况 关于etcd的 ...