light1076Get the Containers

思路:这题应该来说比lightoj1048简单多了,,,有n个输奶管,里面有一定的牛奶,现在有m个存储罐用来装这些牛奶,规则是一个管子里面的牛奶不能分开装,多个管子里面的牛奶可以混合装,混装的时候只能按照给定的顺序装,求满足条件的单个罐子的最小容积。显然是二分容积值,low = max(A[i],A[i + 1]),high = A[1] + [2] + ... + A[n]。

// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <climits>
using namespace std;
// #define DEBUG
#ifdef DEBUG
#define debug(...) printf( __VA_ARGS__ )
#else
#define debug(...)
#endif
#define CLR(x) memset(x, 0,sizeof x)
#define MEM(x,y) memset(x, y,sizeof x)
#define pk push_back
template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;}
template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;}
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
const double eps = 1e-10;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 1010;
int A[maxn];
int n, m;
bool check(int x){
	int sum = 0, ans = 0;
	for (int i = 1;i <= n;++i){
		while(sum + A[i] <= x && i <= n){
			sum += A[i];
			i++;
		}
		ans++;
		i--;
		sum = 0;
	}
	// cout << "mid = " << x << endl;
	// cout << "ans = " << ans << endl;
	return ans <= m;
}
int Solve(int low,int high){
	int ans;
	while(low < high){
		int mid = (low + high) / 2;
		if (check(mid)) {
			high = mid;
		}
		else low = mid + 1;//ans > n
	}
	return high;
}
int main()
{	
	// freopen("in.txt","r",stdin);
	// freopen("out.txt","w",stdout);
	int t, icase = 0;
	scanf("%d",&t);
	while(t--){
		int high = 0, low = 0;
		scanf("%d%d",&n,&m);
		for (int i = 1;i <= n;++i){
			scanf("%d",&A[i]);
			high += A[i];
			low = max(low, A[i]);
		}
		int ans = Solve(low, high);
		printf("Case %d: %d\n", ++icase, ans);
	}
	return 0;
}


你可能感兴趣的:(二分,lightoj)