user-0 提问: 【求助】关于贪心算法的题，始终无法AC！

回复:
user: user-0
content: 引用 3 楼 FancyMouse 的回复:题目有说输入的C个数有序么？ 题目没说输入有序

user: user-1
content: 引用 8 楼 ls1160 的回复:[quote=引用 6 楼 FancyMouse 的回复:] [quote=引用 4 楼 ls1160 的回复:] [quote=引用 3 楼 FancyMouse 的回复:] 题目有说输入的C个数有序么？ 题目没说输入有序[/quote] 我的意思是你的代码必须在输入有序的时候才对……[/quote] 谢谢，我把前面也排序了之后，就能够测试通过了。只是，我的这个方法可能有点愚笨， 数据读入之前排序，处理之后再排序，然后按照贪心思想求解。 不知道大神有什么好的思路嘛？或者对于其中的处理有更好的解法？ 谢谢哈~[/quote] 排个序又没啥……你这办法可以了。

user: user-0
content: 引用 6 楼 FancyMouse 的回复:[quote=引用 4 楼 ls1160 的回复:] [quote=引用 3 楼 FancyMouse 的回复:] 题目有说输入的C个数有序么？ 题目没说输入有序[/quote] 我的意思是你的代码必须在输入有序的时候才对……[/quote] 谢谢，我把前面也排序了之后，就能够测试通过了。只是，我的这个方法可能有点愚笨， 数据读入之前排序，处理之后再排序，然后按照贪心思想求解。 不知道大神有什么好的思路嘛？或者对于其中的处理有更好的解法？ 谢谢哈~

user: user-0
content: 引用 6 楼 FancyMouse 的回复:[quote=引用 4 楼 ls1160 的回复:] [quote=引用 3 楼 FancyMouse 的回复:] 题目有说输入的C个数有序么？ 题目没说输入有序[/quote] 我的意思是你的代码必须在输入有序的时候才对……[/quote] 恩恩！是的，我也发现了，我现在修改了一下。正在测试。谢谢~

user: user-1
content: 引用 4 楼 ls1160 的回复:[quote=引用 3 楼 FancyMouse 的回复:] 题目有说输入的C个数有序么？ 题目没说输入有序[/quote] 我的意思是你的代码必须在输入有序的时候才对……

user: user-0
content: 引用 2 楼 ALNG 的回复:不用C++的话，用个堆来保留一定数量的最大的缺口也可以。现成的multiset, 不用可惜。   #include <stdio.h> #include <set>  /* flag to see if a stall is occupied */ int occupied[200];  int check(int num_stall, int num_gap);  int main() { 	int board, cow, stall, t; 	scanf("%d%d%d",&board, &stall, &cow); 	for(int i=0; i<cow; ++i) 	{ 		scanf("%d", &t); 		occupied[--t]=1; 	} 	 	printf("%d",check(stall, --board)); 	 	return 0; }  void get_range(int& beg, int& end, int num_stall) { 	for(int i=0; i<num_stall; ++i) 		if(occupied[i]) 		{ 			beg=i; 			break; 		} 	for(int i=num_stall-1; i>=0; --i) 		if(occupied[i]) 		{ 			end=i; 			break; 		} }  std::multiset<int> gaps;  void check_store(int cur_gap, int gap_count) { 	if(gaps.size()<(unsigned)gap_count) 		gaps.insert(cur_gap); 	else if(*gaps.begin()<cur_gap) 	{ 		gaps.erase(gaps.begin()); 		gaps.insert(cur_gap); 	} }   int check(int num_stall, int num_gap) { 	int beg, end, len, cur_gap; 	bool have_cow; 	 	get_range(beg,end,num_stall); 	len=end-beg+1; // naive length of board 	 	// now we find within beg and end num_board-1 largest gap 	// this can be done with a single scan 	cur_gap=0; 	have_cow=true; 	for(int i=beg+1;i<end; ++i) 	{ 		switch( (occupied[i]<<1)+have_cow) 		{ 		case 0: // neither this and prev has cow 			++cur_gap; 			break; 		case 1: // this is not occupied, but prev is occupied 			have_cow=false; 			cur_gap=1; 			break; 		case 2: // this occupied, but prev is empty 			check_store(cur_gap, num_board); 			//cur_gap=0; 			have_cow=true; 			break; 		}		 	} 	for(std::multiset<int>::iterator i=gaps.begin(); i!=gaps.end(); ++i) 		len-=*i; 	return len; }   对如下的测试数据，我的结果是401： 10 500 120 3  4  6  8  14 15  16  17  21 25  26  27  30  31  40  41  42  43 100 37 96 77 55 3 74 66 25 68 350 463 489 496 424 303 325 317 398 408 416 438 85 76 98 96 12 55 63 78 96 102 466 385 386 475 112 363 354 425 225 226 217 238 233 239 247 248 246 244 250 258 265 266 267 269 270 271 272 277 279 285 286 287 289 290 291 292 295 296 297 299 310 311 312 313 315 447 448 459 438 437 433 426 424 423 433 432 410 400 375 376 377 379 381 383 384 385 386 387 392 393 谢谢你的回复~至于你说的multiset 和线性排序，我没学过，得自己学下了。 1、你上面的check_store(cur_gap, num_board);中应该是num_gap吧； 2、你的测试数据应该294，和我后来修改后的一样， 3、放到OJ里面测试的话，有点问题；

user: user-2
content: 不用C++的话，用个堆来保留一定数量的最大的缺口也可以。现成的multiset, 不用可惜。   #include <stdio.h> #include <set>  /* flag to see if a stall is occupied */ int occupied[200];  int check(int num_stall, int num_gap);  int main() { 	int board, cow, stall, t; 	scanf("%d%d%d",&board, &stall, &cow); 	for(int i=0; i<cow; ++i) 	{ 		scanf("%d", &t); 		occupied[--t]=1; 	} 	 	printf("%d",check(stall, --board)); 	 	return 0; }  void get_range(int& beg, int& end, int num_stall) { 	for(int i=0; i<num_stall; ++i) 		if(occupied[i]) 		{ 			beg=i; 			break; 		} 	for(int i=num_stall-1; i>=0; --i) 		if(occupied[i]) 		{ 			end=i; 			break; 		} }  std::multiset<int> gaps;  void check_store(int cur_gap, int gap_count) { 	if(gaps.size()<(unsigned)gap_count) 		gaps.insert(cur_gap); 	else if(*gaps.begin()<cur_gap) 	{ 		gaps.erase(gaps.begin()); 		gaps.insert(cur_gap); 	} }   int check(int num_stall, int num_gap) { 	int beg, end, len, cur_gap; 	bool have_cow; 	 	get_range(beg,end,num_stall); 	len=end-beg+1; // naive length of board 	 	// now we find within beg and end num_board-1 largest gap 	// this can be done with a single scan 	cur_gap=0; 	have_cow=true; 	for(int i=beg+1;i<end; ++i) 	{ 		switch( (occupied[i]<<1)+have_cow) 		{ 		case 0: // neither this and prev has cow 			++cur_gap; 			break; 		case 1: // this is not occupied, but prev is occupied 			have_cow=false; 			cur_gap=1; 			break; 		case 2: // this occupied, but prev is empty 			check_store(cur_gap, num_board); 			//cur_gap=0; 			have_cow=true; 			break; 		}		 	} 	for(std::multiset<int>::iterator i=gaps.begin(); i!=gaps.end(); ++i) 		len-=*i; 	return len; }   对如下的测试数据，我的结果是401： 10 500 120 3  4  6  8  14 15  16  17  21 25  26  27  30  31  40  41  42  43 100 37 96 77 55 3 74 66 25 68 350 463 489 496 424 303 325 317 398 408 416 438 85 76 98 96 12 55 63 78 96 102 466 385 386 475 112 363 354 425 225 226 217 238 233 239 247 248 246 244 250 258 265 266 267 269 270 271 272 277 279 285 286 287 289 290 291 292 295 296 297 299 310 311 312 313 315 447 448 459 438 437 433 426 424 423 433 432 410 400 375 376 377 379 381 383 384 385 386 387 392 393

user: user-2
content: 确实是个贪心问题。似乎不需要排序，只要线性扫描一遍就可以了。我再瞅瞅。

user: user-1
content: 题目有说输入的C个数有序么？