JOJ2510:Product

There are multiple test cases, the first line of each test case is a integer n. (2<=n<=20) The next line have n integers (every integer in the range [1,1000]). We can divide these n integers into two parts and get the sum of the integers in these two parts, define them as sumA and sumB. Please calc the max number of sumA*sumB and output it in a single line.

Sample Input

3
5 3 7
2
4 9

Sample Output

56
36

Hint

(5,3),(7)  sumA=8  sumB=7  sumA*sumB=56
(5),(3,7)  sumA=5  sumB=10 sumA*sumB=50
(3),(5,7)  sumA=3  sumB=12 sumA*sumB=36
(),(3,5,7) sumA=0  sumB=15 sumA*sumB=0
The max is 56.


初看这道题,就知道是水题,草草地写了一个枚举子集的程序,结果TLE了,不过觉得这个思想挺好的,贴下代码吧

#include <cstdio>
#include <iostream>
using namespace std;

int a[21];
int n;

int odd(int x)
{
    int dig = 0;
    int sum = 0;
    while (x)
    {
        if (x & 1)
            sum += a[dig];
        x >>= 1;
        dig++;
    }
    return sum;
}

int main()
{
    while (scanf("%d", &n) != EOF)
    {
        int ans = 0;
        for (int i = 0; i < n; ++i)
            scanf("%d", &a[i]);
        int mask = (1 << n) - 1;
        for (int sub = mask; sub; sub = (sub - 1) & mask)
        {
            if (ans < odd(mask - sub) * odd(sub))
                ans = odd(mask - sub) * odd(sub);
        }
        printf("%d\n", ans);
    }
    return 0;
}

AC代码就是DFS....没什么可说的了....

AC代码:

#include <cstdio>
#include <cstring>
using namespace std;

int n, sum, max, s;
int num[21];

void dfs(int t, int temp)
{
    if (t == n)
    {
        if (temp * (sum - temp) > max)
            max = temp * (sum - temp);
    }
    else
    {
        for (int j = 0; j < 2; ++j)
        {
            dfs(t + 1, temp + j * num[t]);
        }
    }
}

int main()
{
    while (scanf("%d", &n) != EOF)
    {
        max = sum = s = 0;
        for (int i = 0; i < n; ++i)
        {
            scanf("%d", &num[i]);
            sum += num[i];
        }
        dfs(0, s);
        printf("%d\n", max);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值