4168. I-The brute force problem
Time Limit: 1.0 Seconds Memory Limit: 65536K
Total Runs: 233 Accepted Runs: 70
Xiao Ming is very interesting for array. He given a sorted positive integer array and an integer n.
We need add elements to the array such that the sum of subset of array cover the range [1, n]. You must return the minimum number of add elements.
Xiao Ming worry about you can't understand this problem. Now, he gives you an example:
There is an array [1, 3], n = 6, the answer is 1. Because we only need to add 2 into array. After add operator, the array is [1,2,3]. The subsets are: [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]. Possible sums are 1, 2, 3, 4, 5, 6, which now covers the range [1, 6].
Input
The input consists of multiple test cases. The first line contains an integer T
T, indicating the number of test cases.
Each case contains two integers m,n
m,n, m
m means the number of elements in array, n
n means the cover range.(1≤m≤105,1≤n≤2147483647)
(1≤m≤105,1≤n≤2147483647).
Then comes a line with m
m integers.
Output
Return the minimum number of add elements.
Sample Input
1
3 20
1 5 10
Sample Output
2
【分析】
一开始一直觉得这是个NP问题,无法证明数据的合法性,也就是说给出一组数据,无法证明这组数组答案是否为0....
想了N久找了学长....最后还是个NP问题....后来知道做法的时候发现自己真蠢....
如果需要证明数据是否合法的确是个NP问题,但是这道题,可以考虑,如果我当前能组合出[1,now]的所有数,那么如果我当前a[i]>now+1,也就是a[i]和now中间有缺数字,那么就需要添加一个now+1来使得now+1这个数存在于这个集合中,当增加一个now+1之后,区间从[1,now]变成[1,2*now+1],然后重复上述步骤....初始时now=0
【代码】
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
long long a[110000];
int main()
{
int pp;scanf("%d",&pp);
while (pp--)
{
long long m;
int n;scanf("%d%lld",&n,&m);
for (int i=0;i<n;i++)
scanf("%lld",&a[i]);
sort(a,a+n);
long long ans=0;
long long now=0;
for (int i=0;i<n&&now<m;i++)
if (now<a[i]-1)
ans++,now=now*2+1,i--;
else now+=a[i];
while (now<m)
ans++,now=now*2+1;
printf("%lld\n",ans);
}
return 0;
}