题解 P4871 【Oier们的镜子(mirror)】
【题意】定义有根树上一个结点的权值等于整个子树内的节点权值和,现给出
【做法】考虑状压dp,设
即考虑让
【复杂度的推导】
总时间复杂度为
#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int n,w[15],sum[1<<15];
int lmt,f[16][1<<15];
inline int lbt(int x) {return x&-x;}
inline void add(int&x,int y) {if((x+=y)>=mod) x-=mod;}
int main() {
scanf("%d",&n);
for(int i=0; i<n; ++i) scanf("%d",w+i); sort(w,w+n);
for(int i=0; i<n; ++i) sum[1<<i]=w[i]; lmt=1<<n;
for(int i=0; i<lmt; ++i) {
if(i!=lbt(i)) sum[i]=sum[i-lbt(i)]+sum[lbt(i)];
}
f[0][0]=1;
for(int i=0; i<n; ++i) {
for(int j=0; j<lmt; ++j) if(f[i][j]) {
add(f[i+1][j|(1<<i)],f[i][j]);
for(int k=j; k; k=(k-1)&j) if(w[i]==sum[k]) {
add(f[i+1][j^k],f[i][j]);
if(k==lbt(k)) add(f[i+1][j^k],f[i][j]);
}
}
}
int ans=0;
for(int i=0; i<lmt; ++i) {
add(ans,f[n][i]);
}
printf("%d\n",ans);
return 0;
}