1249.D.陆历川爱合并
Time Limit: 1000 MS Memory Limit: 131072 KB
Total Submission(s): 18 Accepted Submission(s): 6
Description
Lulichuan have a sorted sequences, he want to merge these sequences,every time he can chose k elements to merge, every operating cost the Sum of the sequnces, But the total cost should no more than T, so Lulichuan want to know the samllest k .
Input
The first line of input contains an integer T_T, the number of test cases. T_T test cases follow.(0 < T_T <= 1000)
For each test case, the first line consists two integers N (2≤N≤100000) and T (∑Ni=1ai<t<231)< style="box-sizing: border-box;" span="">.
In the next line there are N integers a1,a2,a3,...,aN(∀i,0≤ai≤1000).
Output
For each test cases, output the smallest k.
Sample Input
13 153 4 4
Sample Output
Case #1: 3
Hint
K = 2 sum = (3 + 4) + (3 + 4 + 4) > 15
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
long long a[100005];
long long b[100005];
int main()
{
int t;
scanf("%d", &t);
int cnt0 = 0;
while(t --)
{
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
int n;
int limit;
scanf("%d %d", &n, &limit);
for(int i = 1; i <= n; i ++)
{
scanf("%lld", &a[i]);
}
sort(a + 1, a + n + 1);
int left = 2;
int right = n;
int i;
while(left < right)
{
i = (left + right)/2;
long long ans = 0;
int flag = 1;int cnt1 = 1;int cnt2 = 1;int cnt3 = 1; //cnt1 用来计算a用到哪里 cnt2 用来计算b用到哪里 cnt3 用来计算b现在有多少元素
int first = 1;
while(cnt1 <= n||cnt2 < cnt3)
{
if(first)
{
b[cnt3] = 0;
int num;
if((n - i)%(i - 1) == 0)
num = i;
else
num = (n - i)%(i - 1) + 1;
for(int k = 0;k < num&&(cnt1 <= n||cnt2 < cnt3); k ++)
{
b[cnt3] += a[cnt1 ++];
}
ans += b[cnt3];
first = 0;
}
else
{
++ cnt3;
b[cnt3] = 0;
for(int k = 0; k < i&&(cnt1 <= n||cnt2 < cnt3); k ++)
{
if(b[cnt2] <= a[cnt1]&&cnt2 < cnt3)
{
b[cnt3] += b[cnt2 ++];
}
else if(b[cnt2] > a[cnt1]&&cnt1 <= n)
{
b[cnt3] += a[cnt1 ++];
}
else if(cnt1 <= n&&cnt2 >= cnt3)
{
b[cnt3] += a[cnt1 ++];
}
else if(cnt1 > n&&cnt2 < cnt3)
{
b[cnt3] += b[cnt2 ++];
}
}
ans += b[cnt3];
}
if(ans > limit)
{
left = i + 1;
flag = 0;
break;
}
}
if(flag)
right = i;
}
printf("Case #%d: %d\n", ++cnt0, left);
}
return 0;
}