您的位置:首页 > 其它

POJ1050总结 二分+判定

2011-10-09 17:55 405 查看
#include<iostream>
using namespace std;

#define inf 100000000
const int MAX = 505;
int data[MAX];
int isPart[MAX];
int M;
int K;

int calculatePart(int size){
memset(isPart, 0, sizeof(isPart));
int i = M - 1;
int count = 1;
__int64 sum = 0;
while(i >= 0){
if(sum + data[i] > size){
count++;
sum = data[i];
isPart[i] = 1;
}
else
{
sum += data[i];
}
i--;
}
return count;
}

int binaryFind(int min, int max){
int mid = 0;
while(min < max)
{
mid = (min + max) / 2;
if(calculatePart(mid) > K){
min = mid + 1;
}
else
{
max = mid;
}
}
return max;
}

int main()
{
//	freopen("1505.txt", "r", stdin);
int testcases = 0;
cin >> testcases;
while(testcases--)
{
cin >> M >> K;
int min = 0;
int max = 0;
int i = 0;
for(i = 0; i < M; i++)
{
cin >> data[i];
if(min < data[i])
min = data[i];
max += data[i];
}

int partNum = binaryFind(min, max);
//		cout << partNum << endl;
int part = calculatePart(partNum);
//		cout << part << endl;
for(i = 0; i < M - 1 && part < K; i++)
{
if(isPart[i] == 0)
{
isPart[i] = 1;
part++;
}
}
for(i = 0; i < M - 1; i++)
{
cout << data[i] << " ";
if(isPart[i] == 1)
cout << "/ ";
}
cout << data[i] << endl;

}
return 0;
}
解答本题的核心在于利用二分查找的方法,在最小和最大的“段和”间找最合适的哪个“段和”。如果能方便的判断出最合适的“段和”的话,那问题自然就容易解决,关键是需要查找了,二分查找是个不错的选择!最后有点更加重要,把多余的人从前往后安排,已达到最优解决,值得回味啊!说不清楚,看代码即可明白!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: