类似于银行家算法的一个题目

j8daxue 2009-11-11 04:20:11
描述

歌手到幼儿园跟小朋友玩,她到达的时候小朋友们正在争积木,小朋友都想要更多的积木砌一个自己喜欢的图形,砌完就可以和歌手合照。同时歌手手上还有一些积木,她可以把手上的这些积木全部给一个小朋友,然后等该小朋友砌完后就可以收回所发的积木和该小朋友原先手上的积木。但她不知道能否让所有的小朋友都和她合照,聪明的你可以帮助她吗?

输入


输入包含多组数据。

第一行是n和s 都<=10000,表示一共有n个小朋友,歌手手上有s个积木。以下有n行,每行有两个正整数,a和b, 1<=a,b<=10^9,表示第i个小朋友手上有a个积木,还需要b个积木才能够砌完。

输入n=s=0时候结束


输出

如果可以输出YES,否则输出NO

样例输入

2 2
1 4
2 1
2 2
1 4
1 1
0 0


样例输出

YES
NO
题目:http://acm.nuaa.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1323

我的基本想法
1.需要分配的资源按照需求排序(multiset)。
2.把空闲资源s插入到这个序列中。
3.如果只剩余一个元素,则返回true。
4.如果s在序列首,则返回false;最末尾的话,则返回true。
5.如果在中间,则从序列开始,到s所在地方把之前所占有的资源累加,并且把s之前,包括s全删除。再次插入(转2)
但总是超时。。。。也不知道思路问题还是代码问题
代码

typedef struct SRes
{
int owned;
int need;
SRes(int a, int b)
{
owned = a;
need = b;
}
bool operator < (SRes*& other)
{
return this->need < other->need;
}
}* PRES;

struct Less_PRES{

bool operator()(PRES p1, PRES p2)
{
return p1->need < p2->need;
}
};

bool res_alloc(int n ,int s,multiset<PRES,Less_PRES>& setRes)
{
typedef multiset<PRES,Less_PRES>::iterator IT;
SRes tmp(0,s);
while(setRes.size())
{
IT itr = setRes.insert(&tmp);
if(itr == setRes.begin())
{
return false;
}
else
{
itr ++;
if(itr == setRes.end())
{
return true;
}
for(IT it = setRes.begin(); it != itr ; )
{
tmp.need += (*it)->owned;
setRes.erase(it++);
}
}
}
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
int n ,s ,owned,need;
vector<bool> out;
multiset<PRES,Less_PRES> setRes;
while(1)
{
setRes.clear();
cin>>n>>s;
if(n == 0 && s == 0)
break;
for(int i = 0 ; i < n ; i ++)
{
cin>>owned>>need;
setRes.insert(new SRes(owned,need));
}
out.push_back(res_alloc(n,s,setRes));
}
for(unsigned int i = 0 ; i < out.size() ; ++i)
{
if(out[i]) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
...全文
258 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhli2008 2010-12-12
  • 打赏
  • 举报
回复
典型的银行家算法吗
「已注销」 2009-11-13
  • 打赏
  • 举报
回复
打酱油路过...
j8daxue 2009-11-12
  • 打赏
  • 举报
回复

bool res_alloc(int n ,int s,SRes *res)
{
qsort(res,n,sizeof(SRes),cmp);
for(int i = 0 ; i < n ; i ++)
{
if(s < res[i].need)
{
return false;
}
else s+= res[i].owned;
}
return true;
}

这样还是超时,其实怀疑方法不对,因为我的代码有1000+byte,别人通过的代码长度是我的一半
绿色夹克衫 2009-11-12
  • 打赏
  • 举报
回复
这样也会超时么?排10000个也就是0.05M吧。
把cin>>n>>s换scanf应该可以快一些,但不至于有这样大的差距。

[Quote=引用 8 楼 j8daxue 的回复:]
C/C++ codebool res_alloc(int n ,int s,SRes*res)
{
qsort(res,n,sizeof(SRes),cmp);for(int i=0 ; i< n ; i++)
{if(s< res[i].need)
{returnfalse;
}else s+= res[i].owned;
}returntrue;
}
这样还是超时,其实怀疑方法不对,因为我的代码有1000+byte,别人通过的代码长度是我的一半
[/Quote]
pehaps 2009-11-11
  • 打赏
  • 举报
回复
up吧!感觉貌似也没什么再快的了!即使快,也不会有多少提升!
绿色夹克衫 2009-11-11
  • 打赏
  • 举报
回复
应该是快排+遍历快,复杂度n*log(n) + n,multiset是平衡二叉树,效率应该是2*n*log(n),
稍微高一点,但属于同一数量级的!

[Quote=引用 4 楼 j8daxue 的回复:]
引用 3 楼 litaoye 的回复:

排序了之后还得逐个比较,累加啊。
不过我第一次提交不是用快排+数组。直接用multiset,不知哪个效率高?
[/Quote]
berryluo 2009-11-11
  • 打赏
  • 举报
回复
按b排序 nlogn 的快排加一次的线性扫描,没有更快的了吧
j8daxue 2009-11-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 litaoye 的回复:]
10000个排序应该不会超时吧!

引用 2 楼 j8daxue 的回复:
引用 1 楼 litaoye 的回复:
按照小朋友的所需的积木数量,从少到多排个序,从要的最少的开始给,可以么?

第一次就这样想的。
我是第二次提交。明显的,你这个方法没我说的那个效率高。

[/Quote]
排序了之后还得逐个比较,累加啊。
不过我第一次提交不是用快排+数组。直接用multiset,不知哪个效率高?
绿色夹克衫 2009-11-11
  • 打赏
  • 举报
回复
10000个排序应该不会超时吧!

[Quote=引用 2 楼 j8daxue 的回复:]
引用 1 楼 litaoye 的回复:
按照小朋友的所需的积木数量,从少到多排个序,从要的最少的开始给,可以么?

第一次就这样想的。
我是第二次提交。明显的,你这个方法没我说的那个效率高。
[/Quote]
j8daxue 2009-11-11
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 litaoye 的回复:]
按照小朋友的所需的积木数量,从少到多排个序,从要的最少的开始给,可以么?
[/Quote]
第一次就这样想的。
我是第二次提交。明显的,你这个方法没我说的那个效率高。
绿色夹克衫 2009-11-11
  • 打赏
  • 举报
回复
按照小朋友的所需的积木数量,从少到多排个序,从要的最少的开始给,可以么?

33,007

社区成员

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

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