Network Saboteur POJ - 2531 暴力搜索+剪枝技巧

传送门


题目大意:有n个网络节点需要交换数据, 给出这n个节点相互交换数据的花费, 把这n个节点划分成两个子网, 子网内交换数据花费为零, 求划分成两个子网后最大的开销是多大。

解题思路:思来想去没有什么好办法, 一开始以为是个贪心或者dp, 但是不好记忆, 暴力可以。因为是分为两组, 可以分为0组和1组, 那么最大有二十台节点, 那么用二进制即可保存。 对于每种情况计算出开销, 保存最大值即可

剪枝:由于   1101   和 0010  是一样的, 因此不需要重复搜索,  当有四个节点的时候我们只需要搜到 0 1 1 1 就可以了  下一个是 1 0 0 0 就与前面重复了。


代码:

#include <iostream>
#include <cstdio>

using namespace std;
int n;
int W[25][25];
int main()
{
	while(~scanf("%d", &n))
	{
		for(int i=1; i<=n; ++i)
			for(int j=1; j<=n; ++j)
				scanf("%d", &W[i][j]);
		int M = (1 << n)-1;
		int ans = 0;
		int a = 0, b = 0;
		int A[25], B[25];
		for(int i=1; i<M; ++i)
		{
			a = b = 0;
			for(int j=0; j<n; ++j)
				if(1 & (i >> j)) A[a++] = j+1;
				else B[b++] = j+1;
			int cur = 0;
			for(int j=0; j<a; ++j)
				for(int k=0; k<b; ++k)
					cur += W[A[j]][B[k]];
			ans = max(ans, cur);
		}
		printf("%d\n", ans);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值