首页 > 其他分享 >SPOJ SP32058 R6PL - Harbinger vs Sciencepal

SPOJ SP32058 R6PL - Harbinger vs Sciencepal

时间:2023-01-09 19:11:55浏览次数:60  
标签:10 SP32058 le int 复杂度 Sciencepal cin Harbinger 2n

链接
难度:\(\texttt{17/21}\)


\(T\) 组数据。

有 \(n\) 组,每组有 \(2\) 个数 \(x,y\),问把每组的一个数分配到一组另一个数分配到另一组两组数字和差的绝对值最小是多少。

数据范围:\(1\le T\le 10,1\le n\le 200,1\le x,y\le 250\)。


有点套路的题目。


首先能想到用 01 背包 \(f_{i,j}\) 代表到第 \(i\) 组,第一组数的和 \(-\) 第二组数的和差为 \(j\) 是否可行,便可得转移方程 \(f_{i,j}=f_{i-1,j-(x-y)}|f_{i-1,j+(x-y)}\)。

这样的单次时间复杂度是 \(O(2n\sum |x-y|)\),计算量已经达到了 \(2\times 10^7\),尝试优化。

发现 \(f_{i,j}\) 只会为 \(\texttt{0/1}\),且操作对应的正是位移,便考虑用 bitset 优化,单次时间复杂度便为 \(O(\frac{2n\sum |x-y|}{w})\),\(w=32/64\)。


# include <bits/stdc++.h>
using namespace std;
const int N = 200, C = 250, T = 2;
bitset <(N * C << 1) + 100> B [T]; // 有负数开 2 倍
int main () {
	ios :: sync_with_stdio (false);
	cin .tie (0);
	cout .tie (0);
	int t;
	cin >> t;
	while (t --) {
		B [0] .reset (), B [1] .reset ();
		B [0] [N * C + 10] = 1;
		int n;
		cin >> n;
		for (int i = 1, x, y; i <= n; ++ i) {
			cin >> x >> y;
			int c = max (x, y) - min (x, y);
			B [i & 1] = (B [(i & 1) ^ 1] >> c) | (B [(i & 1) ^ 1] << c);// 左移和右移都有
		}
		for (int i = 0; ; ++ i) {
			if (B [n & 1] [N * C + 10 - i] || B [n & 1] [N * C + 10 + i]) {
				cout << i << '\n';
				break;
			}
		}
	}
	return 0;
}

标签:10,SP32058,le,int,复杂度,Sciencepal,cin,Harbinger,2n
From: https://www.cnblogs.com/lhzQAQ/p/17038288.html

相关文章

  • R6PL - Harbinger vs Sciencepal题解
    R6PL-HarbingervsSciencepal题面翻译彩虹6是大学里非常流行的游戏。你的两个朋友小A和小B是优秀的玩家,他们想要参与竞争。所以他们决定组建自己的团队。有2*N的......