码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces1303D Fill The Bag 二进制应用and贪心

时间:2020-02-17 01:09:40      阅读:90      评论:0      收藏:0      [点我收藏+]

标签:targe   long   lld   printf   highlight   $1   scanf   codeforce   大小   

网址:https://codeforces.com/contest/1303/problem/D

题意:

给出空间为$n$的容器和$m$个盒子。这些盒子的大小都是$2^k$的正整数,且可以减半,问使得容器刚好被盒子装满的最小减半次数是多少,如果不可能刚好装满,输出$-1$。

题解:

统计$2^k$大小的盒子有多少个,然后从低位到高位贪心,因为高位的一定需要减半才能到低位,所以就会增加减半次数,而低位变成高位却无影响。对于某一位$i$,如果它是$1$,那么对于这一位,如果已经没有了大小是$2^i$的盒子,则需要从$i+1$位的减半一次,$i+1$位上的盒子数是$-1$也没有关系,因为它会从$(i+1)+1$位拿过来,类似于减法退位。如果有剩下的,就直接合并到$i+1$位,最后输出减半次数就是答案。

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int cnt[65];
int solve()
{
	memset(cnt, 0, sizeof(cnt));
	ll n, sum = 0;
	int m, a;
	scanf("%lld%d", &n, &m);
	for (int i = 1; i <= m; ++i)
	{
		scanf("%d", &a);
		sum += a;
		int tmp = 0;
		while (a > 1)
			++tmp, a >>= 1;
		++cnt[tmp];
	}
	if (sum < n)
		return printf("-1\n"), 0;
	int ans = 0;
	for (int i = 0; i <= 63; ++i)
	{
		int x = (n >> i) & 1;
		cnt[i] -= x;
		if (cnt[i] >= 2)
			cnt[i + 1] += cnt[i] / 2, cnt[i] -= (cnt[i] / 2) * 2;
		if (cnt[i] < 0)
			--cnt[i + 1], ++ans;
	}
	return printf("%d\n", ans), 0;
}
int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
		solve();
	return 0;
}

 

codeforces1303D Fill The Bag 二进制应用and贪心

标签:targe   long   lld   printf   highlight   $1   scanf   codeforce   大小   

原文地址:https://www.cnblogs.com/Aya-Uchida/p/12319619.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!