高维前缀和~~

1.首先求某个二进制状态下所有他的超集的和是多少~

for(int i = 0; i< 3 ;++i){
    for(int j = 0; j<8 ;++j)
        if( !(j&(1<<(i))) ) dp[j] +=  dp[j|(1<<(i))];

         大体意思就是对于某个位置 i 来说~如果存在某个状态 j 下他的 i 位不存在,那么这个状态就一定存在他的一个超集                 (j |(1<<i))这样的话就使dp[j]+=dp[j|(1<<i)]就好了。

         这里有个模拟,让你更方便了解过程:

#include<bits/stdc++.h>
using namespace std;
int dp[10];
vector<int>G[10];
void trans(int x) {
	int a = x % 2; x /= 2;
	int b = x % 2; x /= 2;
	int c = x % 2; x /= 2;
	cout << c << b << a ;
}
void print(int x) {
	for (int s = 0; s < G[x].size(); s++) {
		trans(G[x][s]); cout << " ";
	}
}
int main() {
	for (int s = 0; s < 8; s++) {
		G[s].push_back(s);
	}
	memset(dp, -1, sizeof(dp));
	for (int i = 0; i < 3; ++i) {
		cout << i << endl;
		for (int j = 0; j < 8; ++j) {
			if (!(j&(1 << (i))))
			{
				int v = (j | (1 << (i)));
				trans(j); cout << ":"; print(j); cout << endl;
				trans(v); cout << ":"; print(v); cout << endl;
				for (int s = 0; s < G[v].size(); s++) {
					G[j].push_back(G[v][s]);
				}
				dp[j] += dp[j | (1 << (i))];
				cout << endl;
			}
		}
	}
	for (int s = 0; s < 8; s++) {
		trans(s); cout << ":"; print(s); cout << endl;
	}
	return 0;
}

         

2.求某个二进制状态下所有他的子集的和是多少

 

for(int j=0;j<n;j++)
    for(int i=0;i<1<<n;i++)
        if(i&(1<<j)) dp[i]+=dp[i^(1<<j)];

       可以把上一个模拟代码稍微改改就能用了。

全部评论

相关推荐

不愿透露姓名的神秘牛友
11-27 10:28
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
11-27 10:48
点赞 评论 收藏
分享
牛客771574427号:恭喜你,华杰
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务