高维前缀和~~

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)];

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

全部评论

相关推荐

一个菜鸡罢了:哥们,感觉你的简历还是有点问题的,我提几点建议,看看能不能提供一点帮助 1. ”新余学院“别加粗,课程不清楚是否有必要写,感觉版面不如拿来写一下做过的事情,教育经历是你的弱势就尽量少写 2. “干部及社团经历”和“自我评价”删掉 3. 论文后面的“录用”和“小修”啥的都删掉,默认全录用,问了再说,反正小修毕业前肯定能发出来 4. 工作经验和研究成果没有体现你的个人贡献,着重包装一下个人贡献
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务