简单问题的大数据化。相信大家都有一个一定能实现正确输出的方法,最常见的应该是每次都排一次序,取出最大的M种珍珠,判断个中最小的是否大于M个,是的话就将每种珍珠-1后放回,并且最大项链数加1;否则的话就输出当前的最大项链数,如此反复则可。当数据量比较大的时候,这种方法在排序上浪费太多的时间,明显会超时。
既然逐一迭代太耗时,那么二分趋近就是一个很好的解决方案。首先明确最大项链数必然在低值(0)和高值(珍珠总数/ M )之间,然后每一次迭代取两者中值,判断能否搭配出中值的项链数,可以的话则将低值换成中值+1;否则的话将高值换成中值-1,如此反复,直至低值和高值不再保持大小关系为止。由于上述过程保证了低值-1必定能配出,故跳出迭代后需要判断低值的项链数能否配出,可以的话最大项链数就是当前的低值,否则就是当前的低值-1。
至于判断是否能搭配出N条项链,就是判断能否用当前所有的珍珠,去构成N条项链,而其中每条项链都有M颗不同的珍珠。那从贪心的角度理解,对于已给出的每种珍珠数和N,取两者中的较小者(记为min),则总有一种办法可以使得这min个珍珠出现在最小珍珠数的那min条项链上(其中怎样找出这min条项链无需关心,我们只关心结果)。那最后配出的项链上珍珠的总数>=N*M的话,那就表示成功;否则失败。至此,整个问题迎刃而解。
Run Time: 0.01sec
Run Memory: 304KB
Code length: 845Bytes
Submit Time: 2011-12-16 00:40:14
// Problem#: 2015
// Submission#: 1082948
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
using namespace std;
int main()
{
int n, M, i;
int bot, top, mid;
int sum, data[ 1000 ];
while ( scanf( "%d", &n ) && n != 0 ) {
sum = 0;
for ( i = 0; i < n; i++ ) {
scanf( "%d", &data[ i ] );
sum += data[ i ];
}
scanf( "%d", &M );
bot = 0;
top = sum / M;
while ( bot < top ) {
mid = ( bot + top ) / 2;
sum = 0;
for ( i = 0; i < n; i++ )
sum += ( data[ i ] >= mid ? mid: data[ i ] );
sum >= mid * M ? bot = mid + 1: top = mid - 1;
}
sum = 0;
for ( i = 0; i < n; i++ )
sum += ( data[ i ] >= bot ? bot: data[ i ] );
printf( "%d\n", sum >= bot * M ? bot: bot - 1 );
}
return 0;
}
本文介绍了一种使用二分查找法优化解决珠串问题的方法。通过对比逐一迭代法,该方法能在大数据环境下有效减少运行时间。文章详细解释了二分查找的实现逻辑,并给出了具体的代码示例。
515

被折叠的 条评论
为什么被折叠?



