看到一个好题目,今年ACM上海的棍子问题

starfish 2001-11-24 12:27:39
加精
这个题目很有意思,贴出来让大家讨论讨论


木头棍子
源程序名    STICK.??? (pas,c,cpp)
可执行文件名 STICK.exe
输入文件名   STICK.in
输出文件名 STICK.out
一堆木头棍子共有n根,每根棍子的长度和重量都是已知的。棍子可以被一台机器一个接
一个地加工。机器处理一根棍子之前需要准备时间。准备时间是这样定义的:
(a) 第一根棍子的准备时间为1分钟;
(b) 如果刚处理完长度为L,重量为W的棍子,那么如果下一个棍子长Li,宽Wi,并且满足
L>=Li,W>=Wi,这个棍子就不需要准备时间。否则需要1分钟的准备时间。
计算处理完n根棍子所需要的最短的准备时间。比如,你有5根棍子,长度和重量分别为(4
,9),(5,2),(2,1),(3,5),(1,4),最短的准备时间为2。因为可以分成以下两组进行加工:
(4,9)、(3,5)、(1,4)为一组;(5,2)、(2,1)为另一组。
输入
第一行是一个整数n(n<=5000),,第2行是2n个整数,分别是L1,W1,L2,W2,…,Ln,Wn。L和
W的值均不超过10000,相邻两数之间用空格分开。
输出
仅一行,一个整数,所需要的最短时间。
样例
STICK.IN
5
4 9 5 2 2 1 3 5 1 4
STICK.OUT
2

下面是英文原题

The 26 th Annual
ACM International Collegiate
Programming Contest
ASIA Regional - Taejon
Problem B
Wooden Sticks
Input: stick.in
There is a pile of n wooden sticks. The length and weight of each stick are kn
own in advance. The sticks are
to be processed by a woodworking machine in one by one fashion. It needs some
time, called setup time, for
the machine to prepare processing a stick. The setup times are associated with
cleaning operations and
changing tools and shapes in the machine. The setup times of the woodworking m
achine are given as follows:
(a) The setup time for the first wooden stick is 1 minute.
(b) Right after processing a stick of length l and weight w , the machine will
need no setup time for a stick
of length ' l and weight ' w if ' l l £ and ' w w £ . Otherwise, i
t will need 1 minute for setup.
You are to find the minimum setup time to process a given pile of n wooden sti
cks. For example, if you have
five sticks whose pairs of length and weight are ) 9 , 4 ( , ) 2 , 5 ( , ) 1 ,
2 ( , ) 5 , 3 ( , and ) 4 , 1 ( , then the minimum setup
time should be 2 minutes since there is a sequence of pairs ) 4 , 1 ( , ) 5 ,
3 ( , ) 9 , 4 ( , ) 1 , 2 ( , ) 2 , 5 ( .
Input
The input consists of T test cases. The number of test cases ) (T is given in
the first line of the input file. Each
test case consists of two lines: The first line has an integer n , 5000 1 &pou
nd; £ n , that represents the number of
wooden sticks in the test case, and the second line contains n 2 positive inte
gers 1 l , 1 w , 2 l , 2 w , , n l , n w ,
each of magnitude at most 10000 , where i l and i w are the length and weight
of the i th wooden stick,
respectively. The n 2 integers are delimited by one or more spaces.
Output
The output should contain the minimum setup time in minutes, one per line.
Sample Input
(stick.in)
Output for the Sample Input
3
5
4 9 5 2 2 1 3 5 1 4
3
2 2 1 1 2 2
3
1 3 2 2 3 1
2
1
3
...全文
402 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
Chice_wxg 2001-12-04
  • 打赏
  • 举报
回复
99年第一题第二问:
有x个导弹,高度不等,按顺序飞来。而反导弹系统第一次可以到达任意高度,以后每次能到达的高度都要小于上次的高度。问最少要多少反导弹系统才能把所有导弹都拦截。

这是99年第一题第二问的程序:
program rock;
const
h:array [1..8] of integer=(8,7,6,15,4,3,2,1);
{表示导弹高度}
var
mc:array [1..100] of integer;
i,j,l,m,n:integer;
begin
n:=0;
for i:=1 to 10 do mc[i]:=30000;

for i:=1 to 8 do begin
while mc[m]<h[i] do m:=m+1;
l:=0;
for j:=1 to n do
begin
if (h[i]<mc[j]) and (mc[j]<=mc[m]) then
begin
m:=j;
l:=1;
end;
end;
if l=1 then
mc[m]:=h[i]
else
begin
n:=n+1;
mc[n]:=h[i];
end;
end;
writeln(' Min MC:',n);
readln;
end.



^_^ 仅供参考 ^_^
Chice_wxg 2001-12-04
  • 打赏
  • 举报
回复
intfree() 说的很对。

简直是那个题目的翻版。
starfish 2001-12-02
  • 打赏
  • 举报
回复
很显然楼上的算法是错的,你再想想看 :0
tarkey 2001-12-02
  • 打赏
  • 举报
回复
先用贪心法计算出最值,然后用动规求解。
从最大值或者最小值出发,搜索出一条最长路径,然后从列阵中
删除这些元素,继续搜索最长路径。只到队列为空为止。

bjay 2001-12-01
  • 打赏
  • 举报
回复
我认为这是一个基排问题(参见《数据结构》严蔚敏等)。
1、建立N(L,W中的最大值)个空链;
2、按各自L值插入不同的空链中;
3、将各个链按L值由小到大合成一个顺序链,
4、按各自W值插入不同的空链中;
5、将各个链按L值由小到大合成一个顺序链,
最后形成的这个链,从后向前,一旦发现不合条件的情况时间加1。
结果输出就可。
zhaodh 2001-11-30
  • 打赏
  • 举报
回复
1.按长度排序
2.循环直至所有都以标记组
取第一个未标组号
找出按重量降序排列的为一组标记
3.组数即为等待时间
mathe 2001-11-29
  • 打赏
  • 举报
回复
Sorry, we should call sort by
sort(sticks,sticks+n,less1());
ccmouse 2001-11-29
  • 打赏
  • 举报
回复
我先以长度为主关键字,宽度第二排序。
随后从(长度)大到小,若宽度小于某链尾,接上去,否则自己连出一链。
考虑到预先排过序,所有的链尾宽度呈递增,所以正好它插入长度与宽度和自己相差最小的那链。
就这么简单?我对吗?



mathe 2001-11-29
  • 打赏
  • 举报
回复
#include <functional>
#include <vector>
struct Stick{
int width;
int height;
} sticks[N];

//suppose count of Stick is n
struct less1:public binary_function<Stick,Stick,bool>{
bool operator()(const Stick& x,const Stick& y)const{if(x.width!=y.width)return x.width>y.width;else return x.height>y.height;}
}
struct less2:public binary_function<Stick,Stick,bool>{
bool operator()(const Stick& x,const Stick& y)const{return x.height>y.height;}
}
sort(sticks,sticks+n,less1);
typedef map<Stick,const Stick&,less2> StickMap;
StickMap maps;
for(i=0;i<n;i++){
StickMap::iterator it;
it=maps.upper_bound(Sticks[i]);
if(it!=maps.end())
maps.erase(it);
maps[Sticks[i]]=Sticks[i];
}
return maps.size();
mathe 2001-11-27
  • 打赏
  • 举报
回复
Build the DAG as I have said.
sum=0;
for each node in the DAG.
if(count of parent < count of child)
sum+=count of child - count of parent;
The result is the sum.
Interesting?
The problem is how to build the DAG quickly or how to get the sum
without construct the DAG.
laozi 2001-11-27
  • 打赏
  • 举报
回复
我的感觉是一个森林,L越小,W越小,越接近根。每个结点的子结点的L和W都大于该结点的L和W,为了符合题意,需要形成的树最少,且每棵树的分支也要最少。
******************************************************************
第一步,可以确定有多少树
第二步,使每棵树的分支最少
第三步,把树拆开就可以了。
bjay 2001-11-27
  • 打赏
  • 举报
回复
有个想法,没有详细论证:
先用第一个数排序,再用第二个数排序,再判别有几个。
chenggn 2001-11-26
  • 打赏
  • 举报
回复
my mind geedy+dp
rdtt 2001-11-26
  • 打赏
  • 举报
回复
想不到!!
dongmen 2001-11-26
  • 打赏
  • 举报
回复
n^2 就可以了吧,规模不大,hoho
starfish 2001-11-26
  • 打赏
  • 举报
回复
嘿嘿,快要讨论到重点了
Knuth是先贪心,再动归,要把两种算法结合起来使用,呵呵呵呵
不过我发现单纯的贪心也可以做,只不过复杂度大一点,最坏情况下是O(n^2)
Knuth的算法是O(nlogn)
one_add_one 2001-11-26
  • 打赏
  • 举报
回复
其实动态规划可以解决这题,不过空间复杂度较大。。

还有一个算法比较好,我现在想不起来了。。。

:(
one_add_one 2001-11-26
  • 打赏
  • 举报
回复
不能用贪心
along_zju 2001-11-26
  • 打赏
  • 举报
回复
这个题目贪心算法确实很奇怪,反正我觉得没法证明..但是是能通过测试数据的...
starfish 2001-11-25
  • 打赏
  • 举报
回复
如果规模不大的话可以用网络流解决,他的图论模型是最小路径覆盖,但是这里n<=10000,规模太大了:(
加载更多回复(12)

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧