求助 B 的 O(nV) 爆标做法
查看原帖
求助 B 的 O(nV) 爆标做法
809729
SJZ2010楼主2024/7/28 07:50

rt. 我赛时注意到正负数的差只能在 [−2000,2000][-2000, 2000] 之间,因此可以跑 O(nV)O(nV) 的背包,然而没调出来。。。这应该是比 std 的 O(n2V/w)O(n^2V / w) 更优的,求助大佬是哪里的问题。

对拍的结果是如果 nn 很大,直接爆 int 了。

#include <bits/stdc++.h>
using namespace std;

using LL = __int128;
using ll = long long;
using ldb = long double;
using vi = vector < int >;
using ull = unsigned long long;
#define pb push_back
#define ve vector < edge >
#define lowbit(x) ((x) & -(x))
#define me(a, b) memset(a, b, sizeof(a))
#define L(i, j, k) for (int i = j; i <= int(k); i++)
#define R(i, j, k) for (int i = j; i >= int(k); i--)
#define debug cerr << __FILE__ << ": " << __LINE__ << '\n';
#define qio() ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
namespace io {
	char buf[1 << 21], *p1 = buf, *p2 = buf;
	#define gc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
	int read() {
		int res(0), f(1);
		char ch(getchar());
		while (ch < '0' || ch > '9') {
			if (ch == '-')
				f = -1;
			ch = getchar();
		}
		while (ch >= '0' && ch <= '9') {
			res = res * 10 + (ch ^ '0');
			ch = getchar();
		}
		return res * f;
	}
	ll readl() {
		ll res(0);
		int f(1);
		char ch(getchar());
		while (ch < '0' || ch > '9') {
			if (ch == '-')
				f = -1;
			ch = getchar();
		}
		while (ch >= '0' && ch <= '9') {
			res = res * 10 + (ch ^ '0');
			ch = getchar();
		}
		return res * f;
	}
} 
using io::read;
using io::readl;

template < class T >
ostream& operator << (ostream& out, vector < T > v) {
	out << '[';
	if (!v.empty()) {
		L(i, 0, v.size() - 2)
			out << v[i] << ',';
		out << v[v.size() - 1];
	}
	return out << ']';
}
namespace Dbg {
	template < class T >
	void dbg(char *f, T t) {
		cerr << f << '=' << t << endl;
	}
	template < class T, class ...Ar >
	void dbg(char *f, T x, Ar... y) {
		while (*f != ',')
			cerr << *f++;
		cerr << '=' << x << ',';
		dbg(f + 1, y...);
	}
}
#define gdb(...) cerr << "gdb in line " <<__LINE__ << ": ", Dbg::dbg((char*)#__VA_ARGS__,__VA_ARGS__);

const int N = 2e3 + 5; // Adjust
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fll;

int _[N << 1], __[N][N << 1];
int n, *f = &_[N], *g[N];
vi nb, neg, pos;

int main() {
	n = read();
	for (int i = 1, x; i <= n; i++) {
		if ((x = read()) > 0)
			pos.pb(x);
		else if (x < 0)
			neg.pb(x);
		if (x != 0)
			nb.pb(x);
		g[i - 1] = &__[i - 1][N];
	}

	n = nb.size();

	if (pos.empty()) {
		int ans = -inf;
		for (int num : neg)
			ans = max(ans, num);
		return printf("%d\n", ans), 0;
	}
	if (neg.empty()) {
		int ans = 0;
		for (int num : pos)
			ans = max(ans, num);
		return printf("%d\n", ans), 0;
	}

//	f[0] = 1;
	for (int num : nb) {
		f[num]++;
		if (num < 0)
			for (int dlt = max(-2000, -2000 + num); dlt <= min(2000, 2000 + num); dlt++)
				f[dlt] += f[dlt - num] - (dlt == 2 * num), assert(dlt - num >= -2000);
		else
			for (int dlt = min(2000, 2000 + num); dlt >= max(-2000, -2000 + num); dlt--)
				f[dlt] += f[dlt - num] - (dlt == 2 * num), assert(dlt - num <= 2000);
//		for (int dlt = -31; dlt <= 31; dlt++)
//			gdb(num, dlt, f[dlt]);
//		cout << "__________\n";
	}

//	f[0]--;
//	gdb(f[0]);

	int ans = -inf;
	for (int i = 0; i < n; i++) {
		int num = nb[i];
		for (int dlt = -2000; dlt < max(-2000, -2000 + num); dlt++)
			g[i][dlt] = f[dlt];
		for (int dlt = min(2000, 2000 + num) + 1; dlt <= 2000; dlt++)
			g[i][dlt] = f[dlt];
		if (nb[i] > 0)
			for (int dlt = max(-2000, -2000 + nb[i]); dlt <= min(2000, 2000 + num); dlt++)
				g[i][dlt] = f[dlt] - g[i][dlt - nb[i]];
		else
			for (int dlt = min(2000, 2000 + num); dlt >= max(-2000, -2000 + num); dlt--)
				g[i][dlt] = f[dlt] - g[i][dlt - nb[i]];

//		if (!i)
//			gdb(g[i][0], f[0]);
		
//		if (num == 31)
//			gdb(f[0], g[i][0], g[i][-31], f[-31]);

		if (num > 0) {
			for (int dlt = -2000; dlt <= 0; dlt++)
				if (g[i][dlt]) {
					ans = max(ans, dlt + num);
//					if (dlt + num == 30)
//						gdb(dlt, g[i][dlt], num);
				}
		} else {
			for (int dlt = 0; dlt <= 2000; dlt++)
				if (g[i][dlt])
					ans = max(ans, g[i][dlt] + num);
		}

//		gdb(i, ans);
	}
	
	return printf("%d\n", ans), 0;
}
2024/7/28 07:50
加载中...