2018 Multi-University Training Contest 10--HDU 6435 Problem J. CSGO(状态压缩+暴力)

题意:

有 n 个主武器和 m 个副武器,每个武器都有是 s 价值和 x[i] (i = 1...k)属性,通过公式求出一种主武器和副武器组合的最大值。公式:

题解:

abs(x[i]-x[j]) = x[i]-x[j] 或者 x[j]-x[i] 那么我们可以发现 x[i] 只有两种情况,即 x[i] 和 -x[i]。最多有五个属性,那么组合数只有2^k,我以我们可以通过二进制来遍历所有情况。

比如:

主武器\组合数 1 0 0 1
1    sum = s[1] +x[1] -x[1] -x[1] +x[1]
2    sum = s[2] +x[2] -x[2] -x[2] +x[2]
3    sum = s[3] +x[3] -x[3] -x[3] +x[3]
4    sum = s[4] +x[4] -x[4] -x[4] +x[4]

 

副武器\组合数 1 0 0 1
1    sum = s[1] -x[1] +x[1] +x[1] -x[1]
2    sum = s[2] -x[2] +x[2] +x[2] -x[2]
3    sum = s[3] -x[3] +x[3] +x[3] -x[3]
4    sum = s[4] -x[4] +x[4] +x[4] -x[4]

每种组合就取最大值,最后遍历组合的最大值就可以了。

#include <algorithm>
#include  <iostream>
#include   <cstdlib>
#include   <cstring>
#include    <cstdio>
#include    <string>
#include    <vector>
#include    <bitset>
#include     <stack>
#include     <cmath>
#include     <deque>
#include     <queue>
#include      <list>
#include       <set>
#include       <map>
#define mem(a, b) memset(a, b, sizeof(a))
#define pi acos(-1)
using namespace std;
typedef long long ll;

const ll maxn = 1e18;

struct node{
	int s;
	int x[10];
}a[100010], b[100010];

int main(){
	int t;
	scanf("%d", &t);
	while(t--){
		int n, m, k;
		scanf("%d %d %d", &n, &m, &k);
		for(int i = 0; i < n; i++){
			scanf("%d", &a[i].s);
			for(int j = 0; j < k; j++){
				scanf("%d", &a[i].x[j]);
			}
		}
		for(int i = 0; i < m; i++){
			scanf("%d", &b[i].s);
			for(int j = 0; j < k; j++){
				scanf("%d", &b[i].x[j]);
			}
		}
		int maxx = 1 << k;
		ll maxa[35];
		ll maxb[35];
		for(int i = 0; i < 35; i++){
			maxa[i] = maxb[i] = -maxn;
		}
		for(int i = 0; i < maxx; i++){
			for(int j = 0; j < n; j++){
				ll sum = a[j].s;
				for(int q = 0; q < k; q++){
					if(i & (1 << q)){
						sum += a[j].x[q];
					}
					else{
						sum -= a[j].x[q];
					}
				}
				maxa[i] = max(maxa[i], sum);
			}
			for(int j = 0; j < m; j++){
				ll sum = b[j].s;
				for(int q = 0; q < k; q++){
					if(i & (1 << q)){
						sum -= b[j].x[q];
					}
					else{
						sum += b[j].x[q];
					}
				}
				maxb[i] = max(maxb[i], sum);
			}
		}
		ll ans = 0;
		for(int i = 0; i < maxx; i++){
			ans = max(ans, maxa[i]+maxb[i]);
		}
		printf("%lld\n", ans);
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章