zoukankan      html  css  js  c++  java
  • codeforces1303D Fill The Bag 二进制应用+贪心

    网址: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
    "), 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
    ", ans), 0;
    }
    int main()
    {
    	int t;
    	scanf("%d", &t);
    	while (t--)
    		solve();
    	return 0;
    }
    
  • 相关阅读:
    PCA
    Less
    Node.js的运行
    跨域
    Jquery中的Ajax
    JSON
    Ajax应用查询员工信息
    xampp中localhost与DreamWaver站点设置问题
    PHP
    HTTP是什么
  • 原文地址:https://www.cnblogs.com/Aya-Uchida/p/12319619.html
Copyright © 2011-2022 走看看