欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Fruit Baskets 解题报告 Kattis 暴力求解法

程序员文章站 2022-04-01 20:39:36
...

题意:
题目中说了很多废话。其实就是解决一个问题:
给出m个不同质量的物体,并且每个物体的质量大于等于50,
问你在这m个物体中随便取(可以取1个,2个,3个等等),满足取出来的物体的质量和大于200的质量和。
比如给你:
50 60 200
大于200的组合有:
50 200
60 200
50 60 200
对应:
输出 (50+200) + (60 + 200)+(50 + 60 + 200) = 820
即 820
解题思路:
如果枚举:每个重量的物体取或者不取那么就是2的n次方,n为不同质量的种类数。
下面给出一个多项式时间的解决方法:
首先:
注意:如果物体数目大于等于4 任意大于等于4的组合一定满足
这是因为每个物体不少于50。那么我们按照种类数目分类:
1.如果给出的数目小于4:那么直接全排列看看只要产生的组合之和大于200就加上。
2.如果给出的数目大于等于4:
从所有情况减去不符合要求的情况:
总的情况一定是每个质量被选取了 2^(n-1)次 所以出现了2^(n-1)次。对于所有物体就是每个物体质量*2^(n-1)再求和。
不满足情况的一定是存在于那些组合中物体数小于等于3的之中。

那么最后的结果一定是 总的 - 不合情况的
3.需要注意的是使用位运算的要加LL不然直接>>1会溢出。

代码实现

#include <iostream>
#include <cmath>
using namespace std;
int con[42];
long long  sum = 0; int  n;
void zuhe(int a[], int n, int m, int flag)
{   //p[x]=y 取到的第x个元素,是a中的第y个元素
    int index, i, *p;
    p = (int*)malloc(sizeof(int) * m);
    index = 0;
    p[index] = 0; //取第一个元素
    while (true)
    {
        if (p[index] >= n)
        {   //取到底了,回退
            if (index == 0)
            {   //各种情况取完了,不能再回退了
                break;
            }
            index--;//回退到前一个
            p[index]++;//替换元素
        }
        else if (index == m - 1)
        {   //取够了,输出
            int res = 0;
            for (i = 0; i < m; i++)
            {
                res += a[p[i]];
            }
            if (flag == 1)
            {
                if (res >= 200)
                {
                    sum += res;

                }
            } else {
                if (res < 200)
                {
                    sum -= res;
                }
            }

            p[index]++; //替换元素
        }
        else
        {   //多取一个元素
            index++;
            p[index] = p[index - 1] + 1;
        }

    }
}
int main(int argc, char const * argv[])
{
    scanf("%d", &n);
    int tempsum = 0;
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &con[i]);
        tempsum += con[i];
    }
    if (tempsum < 200)
    {
        printf("0\n");
        return 0;
    } else if (tempsum == 200)
    {
        printf("200\n");
        return 0;
    }
    if (n < 4)
    {
        for (int i = 1; i <= n; i++)
        {
            zuhe(con, n, i, 1);
        }
    } else {
        sum += tempsum*pow(2,n - 1);
        for (int i = 1; i <= 3; i++)
        {
            zuhe(con, n, i, 0);
        }
    }
    printf("%lld\n", sum);
    return 0;
}