数组子集

时间:2017-08-06 15:51:38

标签: arrays algorithm dynamic-programming

给定一个大小为n的A数组,只包含正整数。令l为数组A中的最大数。生成大小为0到l的数组B,使得B [j]是数组A的最大子集的大小,其XOR值等于j。

约束: 阵列A的大小可以是1到10000。 数组A中的元素范围为1到1000。

例如:如果数组A有(1,2,3,4),那么将生成数组B,如下所示。

B(0)= 3作为具有XOR值0的最大子集是(1,2,3)并且具有大小3.

B(1)= 2作为具有XOR值1的最大子集是(2,3)并且具有大小2.

B(2)= 2作为具有XOR值2的最大子集是(1,3)并且具有大小2.

B(3)= 2作为具有XOR值3的最大子集是(1,2)并且具有大小2.

B(4)= 4作为XOR值为4的最大子集是(1,2,3,4)并且大小为4.

我的蛮力方法:生成阵列A的所有非空子集并计算每个子集的XOR,并在B [j]中保存具有XOR值j的最大大小子集。

有更有效的方法来做到这一点吗?

1 个答案:

答案 0 :(得分:1)

我相信这会奏效,我已添加了评论意见

#include <iostream>
using namespace std;
#define max(a, b) (a>b?a:b)
int dp[10005][1001]= {0};
int main() {
    // your code goes here
    int n, a[10005]={0}, m, i,j, ans[1005]={0};
    // n denotes number of elements in array, m denotes the range(0, m) where you want to loop
    scanf("%d%d",&n,&m);
    for(i=1; i<=n; i++){
        // taking input
        scanf("%d",&a[i]);
    }
    for(i=0;i<=10000;i++){
        for(j=0;j<=1000;j++){
            dp[i][j] = -1;
        }
    }
    dp[0][0] = 0;
    // dp[i][j] denotes what's the max num of elements whose xor = j using the first i elements
    for(i=1; i<=n; i++){
        for(j=0; j<=1000; j++){
            if(dp[i-1][j] != -1){
                // if j was possible using i-1 elements the using a[i] (a[i]^j) can be made using i elements
                dp[i][j^a[i]] = max(dp[i][j^a[i]], dp[i-1][j]+1);
            }
            dp[i][j] = max(dp[i][j], dp[i-1][j]);
            if(dp[i][j] != -1){
                ans[j] = max(ans[j], dp[i][j]);
            }
        }
    }
    for(i=0;i<=m;i++){
        printf("%d\n", ans[i]);
    }
    return 0;
}

检查http://ideone.com/QuICHN

处的输出