来自dec long contest(codechef)的问题, - http://www.codechef.com/problems/SANSKAR, 我们只需要判断具有差异权重的n个实体是否可以划分给定的部分,每个部分具有相同的wt。 我没有得到AC,所以看了一个解决方案 - http://ideone.com/3hB8lI, 这个解决方案使用按位运算来简化问题,我知道按位操作,但不能得到这个解决方案中使用的方法,我知道复制odrs代码不是一个好主意,但我想知道如何在解决方案中使用按位运算得到答案..
#include<stdio.h>
int main() {
int T, N, K;
scanf("%d", &T);
while(T--) {
scanf("%d %d", &N, &K);
long long a[N];
for(int i=0; i<N; i++)
scanf("%lld", &a[i]);
long long totSans=0;
for(int i=0; i<N; i++)
totSans+=a[i];
long long eachSans;
if(N<K || totSans%K) {
printf("no\n");
continue;
}
if(totSans%K==0)
eachSans=totSans/K;
long long takeAll=0;
int cnt=0;
for(int i=0; i<(1<<N); i++) {
long long sum=0;
for(int j=0; j<N; j++)
if(i & (1<<j))
sum+=a[j];
if(sum==eachSans && !(i & takeAll)) {
takeAll |= i;
cnt++;
}
}
printf(!totSans || cnt>=K ? "yes\n" : "no\n");
}
}
答案 0 :(得分:0)
for(int i=0; i<(1<<N); i++)
用于组合:
它从0b00000
循环到0b11111
以下代码:
long long sum=0;
for(int j=0; j<N; j++)
if(i & (1<<j))
sum+=a[j];
}
根据之前的'掩码'得到总和:
因此,对于i == 0b1010
,sum将为a[1] + a[3]
(掩码索引从右侧开始)。