题目
题目1502:最大值最小化分析
参考http://blog.csdn.net/nanjunxiao/article/details/8145971
第一种方法利用动态规划,比较耗时,耗空间
dp[k][m] 表示k个人前m本书
dp[k][m] = max{ min(dp[ k-1][ i ] , sum( pages[i.....m] )}
也就是说多了一个人,多出的一个人处理后面的几本书,前k-1个人处理前面的几本书
另外一种方法
利用二分查找的方法,查找一个最小的x
该x满足 存在k个连续子序列使每个子序列的和都<= x
代码
// judo1502.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
int work[501][501]= {0};
//int preWork[501] = {0};
//int curWork[501] = {0};
int pages_book[501] = {0};
void judo(int num_book,int num_people){
for(int i = 1;i<num_book+1;i++)
std::cin>>pages_book[i];
//1个人的工作量
for(int book_id = 1;book_id<num_book+1;book_id++){
work[1][book_id] = pages_book[book_id]+work[1][book_id-1];
}
//1本书
for(int People_id = 1;People_id<num_people+1;People_id++){
work[People_id][1] = pages_book[1];
}
int np = 2;
while(np<=num_people){
for(int book_id = 2;book_id<num_book+1;book_id++){
int minwork = work[np-1][book_id];
int subsum = 0;
for(int i = book_id;i>1;i--){//第Np个人完成第i本书往后的书
subsum += pages_book[i];
int temwork = std::max(work[np-1][i-1],subsum);
if(temwork<minwork)
minwork = temwork;
}
work[np][book_id] = minwork;
}
np++;
}
std::cout<<work[num_people][num_book]<<std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
int n;
int k;
int m;
while(std::cin>>n){
for(int i = 0;i<n;i++){
std::cin>>m>>k;
judo(m,k);
}
}
return 0;
}
二分查找
// judo1502new.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
int pages[501];
bool canSplit(int num_books,int num_people,int x){
int s = 0;//每一段的和
int t = 0;//分割线个数
for(int i = 0;i<num_books;i++){
if(pages[i]>x){
return false;
}
if(s+pages[i]>x){
t++;//添加分割线
if(t>num_people-1)//分割线已经大于num_people了,所以只有num_people个人不能实现
return false;
s = pages[i];
}else{
s+=pages[i];
}
}
return true;
}
void judo(int num_books,int num_people ){
for(int i = 0;i<num_books;i++)
std::cin>>pages[i];
int sumpages = 0;
int maxpages = 0;
for(int i = 0;i<num_books;i++){
if(pages[i]>maxpages)
maxpages = pages[i];
sumpages+=pages[i];
}
int L = maxpages;
int R = sumpages;
while(L<R){
int m = L + ((R-L)>>1);
if(canSplit(num_books,num_people,m))
R = m;
else
L = m+1;
}
std::cout<<L<<std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
int n;
int k;
int m;
while(std::cin>>n){
for(int i = 0;i<n;i++){
std::cin>>m>>k;
judo(m,k);
}
}
return 0;
}