题目:http://acm.hdu.edu.cn/showproblem.php?pid=1051

题意可以理解为:给定若干个二元数对,要将这些数对分为不同的组,同一组中的若干个二元数对可以排列成一个顺序,这个顺序使得二元数对按照两个指标中的任意一个指标都是(不严格)递增的,待求的是,在这种分组方式下,最少可以分多少组.

思路:可以先按照两个指标中的一个指标(长度)给这些二元数对排序,再依次序,根据另一个指标(重量)确定第一组最多可以有多少个二元数对,将这些作为一组,然后以同样的方式考虑剩余的数对.

例如给定(4,9), (5,2), (2,1), (3,5) 和 (1,4).

首先,按照第一个指标排序之后为(1,4),(2,1),(3,5),(4,9)(5,2).记为A,B,C,D,E.

然后,对比第二个指标,A之后的B的第二个指标为B2=1<4=A2不满足.C2=5>4=A2满足,所以C可以与A一组.D2=9>5=C2,所以D可以与A和C一组.E2=2<D2=9,所以E和A不能为一组.第一轮结束,得到A,C和D可以为一组,剩余B和E.

接着,考虑剩余的B和E,E2=2>B2=1,所以E和B可以为一组,没有剩余的了.

所以,这样可以分为两组.

C++代码如下

#include<iostream>
#include<algorithm>
using namespace std; //木棍 结构体
struct WoodenStick
{
int Length;
int Weight; //构造函数
WoodenStick(int l=0,int w=0)
{
Length = l;
Weight = w;
}
//设置函数
void Set(int l=0,int w=0)
{
Length = l;
Weight = w;
}
//< 运算符重载,在排序的时候用到
bool operator < (WoodenStick ws)
{
if(Length<ws.Length)
return true;
if(Length == ws.Length)
{
if(Weight<=ws.Weight)
return true;
else return false;
}
else return false;
}
}; //折半插入排序
void BinSort(WoodenStick ws[],int n)
{
for(int i=0;i<n;i++)
{
int low = 0,high = i-1,mid;
while(low<=high)
{
mid = (low+high) / 2;
if(ws[i]<ws[mid])
high = mid - 1;
else
low = mid + 1;
}
WoodenStick temp = ws[i];
for(int j=i;j>low;j--)
ws[j] = ws[j-1];
ws[low] = temp;
}
} int main()
{
int T;
cin >> T;//输入测试数据的组数
while(T--)
{
int n,Length,Weight;//分别为木棍数目 木棍长度 木棍重量
cin >> n;
WoodenStick *ws = new WoodenStick[n]; //木棍结构体数组
for(int i=0;i<n;i++)
{
cin >> Length >> Weight;
ws[i].Set(Length,Weight); //将数据存入木棍结构体数组
}
BinSort(ws,n);//从小到大排序 //调试用 查看排序的结果是否正确
/*
for(int i=0;i<n;i++)
cout << ws[i].Length << " " << ws[i].Weight << endl;
*/ int result = 0;//每一组测试数据的结果
int * IsOk = new int[n];//是否已经分组分配完毕,即是否可以不再考虑这个二元数对了.
for(int i=0;i<n;i++) IsOk[i] = 0;//开始都为0,表示所有的二元数对都没有分配完毕 for(int i=0;i<n;i++)
{
if(!IsOk[i])//针对某个还没有分配的数对
{
int * IndexOfOk = new int[n];//用于记录,可以和i同为一组的数对的下标 ,以便最后可以让它们一并退出系统
int NumOfOk = 0;//用于记录,可以和i同为一组的数对的个数
result ++;//最终结果
IndexOfOk[NumOfOk++] = i;
for(int j=i+1;j<=n-1;j++)//考察i之后的数对是否可以和i同一组
{
if(!IsOk[j])//同样是针对没有分配的数对
{
if(ws[IndexOfOk[NumOfOk-1]].Weight<=ws[j].Weight)//可以和前一个同组
{ // (思考前一个为什么不是ws[j-1])
IndexOfOk[NumOfOk++] = j;//记录可以同为一组的下标
}
}
}
for(int k=0;k<NumOfOk;k++)
IsOk[IndexOfOk[k]] = 1;//根据之前记录的下标,让它们逐一退出系统,之后不再(不用)考虑它们了
}
}
cout << result << endl;
} return 0;
}

上述代码提交AC.

【hdoj_1051】WoodenSticks的更多相关文章

  1. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  2. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  3. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  4. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  5. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

  6. Python高手之路【三】python基础之函数

    基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...

  7. Python高手之路【一】初识python

    Python简介 1:Python的创始人 Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种解释型.面向对象.动态数据类型的高级程序设计语言,由荷兰人Guido ...

  8. 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】

    说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...

  9. 【原】FMDB源码阅读(二)

    [原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...

随机推荐

  1. C++-STL:vector用法总结

    目录 简介 用法 1. 头文件 2. vector的声明及初始化 3. vector基本操作 简介 vector,是同一类型的对象的集合,这一集合可看作可变大小的数组,是顺序容器的一种.相比于数组,应 ...

  2. iOS银联,支付宝,微信,ping++开发文档

    银联支付 银联支付目测只需两个参数 1.tn 其实就是订单号 2.mode 是测试环境还是线上环境 开发步骤 1.首先客户端浏览商品,点击下单,请求到达商户后台 2.商户后台在提交订单信息到银联后台 ...

  3. vue2.0中父子组件之间的通信总结

    父组件: 子组件: 接受父组件的信息: 向父组件发送事件: (其中slot是插槽,可以将父组件中的<p>123</p>插入进来,如果父组件没有插入的内容,则显示slot内部的内 ...

  4. javascript string对象方法replace

    最简单的replace用法是: var str = 'aaaaa9876b0000'; str.replace(/a/g,'A'); 有时候我们希望只是在匹配的位置添加特定的字符: var str = ...

  5. Codeforces Round #553 F Sonya and Informatics

    题目 题目大意 给定一个长为 $n$($2 \le n \le 100$)的01串 $S$ .对 $S$ 进行 $k$($1 \le k \le 10^9$)次操作:等概率地选取两个下标 $i, j$ ...

  6. [洛谷P2044][NOI2012]随机数生成器

    题目大意:给你$m,a,c,X_0,n,g$,求$X_{n+1}=(a\cdot X_n+c) \bmod{m}$,最后输出对$g$取模 题解:矩阵快速幂+龟速乘,这里用了$long\;double$ ...

  7. HDU 3446 有贪心思想的01背包

    Proud Merchants Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) ...

  8. ZOJ3261:Connections in Galaxy War(逆向并查集)

    Connections in Galaxy War Time Limit: 3 Seconds      Memory Limit: 32768 KB 题目链接:http://acm.zju.edu. ...

  9. 迅雷Bolt的ClipSubBindBitmap函数特别说明

    因为在工作中基于迅雷Bolt开发的是IM产品,需要实现自定义用户头像的功能. 但Bolt中对图像的默认拉伸锯齿效果非常明显,所以自己实现了图像拉伸函数,代码已共享,具体可查看:<迅雷Bolt图像 ...

  10. Eclipse CDT 调用printf/cout 控制台(console)无输出

    转摘自:http://blog.csdn.net/dj0379/article/details/6940836 症状描述: 用Eclipse调试程序,执行printf和cout函数,但是console ...