奇怪做法求Hack
查看原帖
奇怪做法求Hack
482642
hank0402楼主2022/10/30 14:06
#include<bits/stdc++.h>
using namespace std;
const int N = 505;
int n, k, a[N], dp[N], sum[N], use[N];
struct Point {
	int x, y;
}p[N];
bool cmp(Point xx, Point yy) {
	if(xx.x != yy.x)return xx.x < yy.x;
	return xx.y < yy.y;
}
int calc(int i, int j) {
	return abs(p[j].x - p[i].x) + abs(p[j].y - p[i].y) - 1;
}
int main() {
	freopen("point.in", "r", stdin);
	freopen("point.out", "w", stdout);
	cin >> n >> k;
	for(int i = 1; i <= n; ++i) cin >> p[i].x >> p[i].y;
	sort(p + 1, p + n + 1, cmp);
	if(k == 0) { // 40pts
		dp[1] = 1;
		for(int i = 2; i <= n; ++i) {
			dp[i] = 1;
			for(int j = 1; j < i; ++j) {
				if((p[i].x == p[j].x && p[i].y == p[j].y + 1)) dp[i] = max(dp[i], dp[j] + 1);
				if(p[i].y == p[j].y && p[i].x == p[j].x + 1) dp[i] = max(dp[i], dp[j] + 1); 
			}
		}
		int ans = 0;
		for(int i = 1; i <= n; ++i) {
			ans = max(ans, dp[i]);
		}
		cout << ans;
		return 0;
	}
	sum[1] = 1; //Maybe 100pts
	for(int i = 2; i <= n; ++i) {
		sum[i] = 1;
		use[i] = 0;
		for(int j = 1; j < i; ++j) {
			if(p[i].x >= p[j].x && p[i].y >= p[j].y) {
				int now = sum[j] + calc(i, j) + 1;
				if(now > sum[i]) {
					sum[i] = now;
					use[i] = use[j] + calc(i, j);
				}
				if(sum[i] == now) {
					use[i] = min(use[i], use[j] + calc(i, j));
				}
			} 
		}
	}
	int ans = 0;
	for(int i = 1; i <= n; ++i) {
		if(use[i] <= k) {
			ans = max(ans, sum[i] + k - use[i]);
		}
	}
	cout << ans;
	return 0;
}

思路是按 x,yx,y 排序后,选出来的序列在这个序列上单调,然后记 sumisum_i 为以 ii 结尾的最大答案,useiuse_i 是在 sumisum_i 的基础上最少的花费,答案是 maxuseiksumi+kusei\max_{use_i\le k} sum_i+k-use_i

2022/10/30 14:06
加载中...