HDU3929(패키징 원리)

1543 단어
제목: Big Coefficients
 
제목: F(x) = (1+x)^a1+(1+x)^a2+...+(1+x)^am, 구계수는 홀수 항목의 개수입니다.
배척 원리: 귀속 형식
dfs(int beg,set S,int sym)
{
     ans+=num(S)*sym;
     for(int i=beg;i<=n;i++)
         dfs(i,S∩A[i],sym*-1);
}

for(int i=1;i<=n;i++)
     dfs(i,A[i],1);

 
각 계수는 하나의 집합이고, 그 기수 차항의 개수는 집합의 개수이며, 알고리즘은 2^(계수의 2진법 안의 1의 개수)이다.
두 집합의 교차는: 예를 들어 계수 w1, w2, 집합의 교차 개수는 2^(w1&w2의 2진법 안의 1의 개수)
홀수 차멱이 교차하는 것이 반드시 홀수 차멱이 아니기 때문에 짝수 개 집합의 교차 개수를 줄이고 식자를 써보면 문제가 복잡해지지 않고 위의 귀속식의sym를 -1에서 -2로 바꾸면 된다.
코드:
#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;
typedef long long LL;

const int N=20;

LL w[N];
LL ans,n;

LL get(LL x)
{
    return x==0? 0:get(x-(x&-x))+1;
}

void dfs(LL beg,LL num,LL sym)
{
    ans+=((LL)1<<get(num))*sym;
    for(LL i=beg+1;i<=n;i++)
        dfs(i,num&w[i],-2*sym);
}

int main()
{
    LL k=1,t,i;
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(i=1;i<=n;i++)
           cin>>w[i];
        ans=0;
        for(i=1;i<=n;i++)
           dfs(i,w[i],1);
        cout<<"Case #"<<k++<<": "<<ans<<endl;
    }
    return 0;
}

좋은 웹페이지 즐겨찾기