CF1427Cパパラッチのハードワーク题解

CF1427Cパパラッチのハードワーク

質問:r * r(r≤500)のマップがあり、開始位置は(1,1)であり、特定の時間に特定の時点で1回出現するn(n≤1e5)人がいます(与えられた場合)時間の昇順で))、最大で何人の人に会えるか尋ねます。

解決策:この質問のアイデアは非常に斬新です。最初は常にbfsを検討していましたが、nが大きすぎるため、書き出すことができませんでした。線形dpになるとはまったく思っていませんでしたこの質問の正解がdpだと最初に聞いたとき、n ^ 2のループのように感じました(dp [i]はi回目までに会える最大人数を表します)が、明らかにそうなります。タイムアウトしました。機能を見つけました。n^ 2のループの場合、rはまったく役に立たないことがわかります。実際、rを使用して2番目のループを最適化します。まず、2点間の距離は最大2rであり、時間は厳密に昇順であるため、iは[0、i-2r]から転送され、最大値は[i-4r、i-2r]の間にある必要があります。 (理由は、ここの値が前の値から更新されているため、この範囲に減らすことができるためです)が、[i-2r、i-1]の場合、この部分を判断する必要があります(次のコードも判断します) [i-4r、i-2r])。この場合、n ^ 2の複雑さをn * rに最適化できます。これは、昨日の問題と少し似ています。
ここに画像の説明を挿入します
コメント欄にご指摘いただきありがとうございます〜

コード

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5+10;
int dp[N];
struct xx {
    
    
	int t, x, y;
}a[N];
int dis(xx a1, xx a2) {
    
    
	return abs(a1.x-a2.x)+abs(a1.y-a2.y);
}
int main() {
    
    
	memset(dp, -1, sizeof dp);
	int r, n;
	scanf("%d%d", &r, &n);
	a[0].x = 1, a[0].y = 1; dp[0] = 0;
	for(int i = 1; i <= n; ++i) scanf("%d%d%d", &a[i].t, &a[i].x, &a[i].y);
	for(int i = 1; i <= n; ++i) {
    
    
		for(int j = max(0, i-1-r*4); j < i; ++j) {
    
    
			if(dp[j] != -1 && a[i].t - a[j].t >= dis(a[i], a[j])) 
				dp[i] = max(dp[i], dp[j]+1);
		}
	}
	int ans = 0;
	for(int i = 1; i <= n; ++i) ans = max(ans, dp[i]);
	printf("%d\n", ans);
	return 0;
}

おすすめ

転載: blog.csdn.net/qq_43408978/article/details/109010714