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

 

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