ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ABC221G Jumping sequence 题解

2021-11-04 22:33:58  阅读:210  来源: 互联网

标签:le sequence int 题解 sum Jumping ans gi define


题面

题意简述:

给定一个长度为 \(n\) 的序列 \(D,\)对于每一个 \(i\) 可以选择向一个方向走长度为 \(D_i\),问是否能走到 \((A,B)\)。

\(\texttt{Data Range:} 1\le n\le 2000,1\le D_i\le 1800,|A|,|B|\le 3.6\times 10^6\)。

首先把曼哈顿距离转化为切比雪夫距离 \((A,B)\rightarrow(A+B,A-B)\)。这样我们就将 \(x\),\(y\) 两维独立了。

对于操作,可以转化成如下形式:

  • up:\((0,d)\rightarrow(-d,d)\);
  • down:\((0,-d)\rightarrow(d,-d)\);
  • left:\((-d,0)\rightarrow(-d,-d)\);
  • right:\((d,0)\rightarrow(d,d)\)。

因此,问题就转化成:

给定 \(n\) 个正整数 \(D_i\),确定一组 \(\{C_i\}\) 使得 \(\sum C_i\times D_i=s\),其中 \(C_i\in\{1,-1\}\)。

假设 \(C_i=1\) 的数的和为 \(a\),\(C_i=-1\) 的数的和为 \(b\),所有数的和为 \(sum\),那么就有:

\[\begin{aligned} a-b&=s\\ b&=a-s\\ b&=sum-b-s\\ 2b&=sum-s \end{aligned} \]

先把 \(sum-s\) 为奇数的情况判掉,然后跑一遍 bitset 优化 01 背包即可。

代码:

#include <bits/stdc++.h>
#define DC int T = gi <int> (); while (T--)
#define DEBUG fprintf(stderr, "Passing [%s] line %d\n", __FUNCTION__, __LINE__)
#define File(x) freopen(x".in","r",stdin); freopen(x".out","w",stdout)
#define fi first
#define se second
#define pb push_back
#define mp make_pair

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int, int> PII;
typedef pair <LL, LL> PLL;

template <typename T>
inline T gi()
{
	T x = 0, f = 1; char c = getchar();
	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return f * x;
}

const int N = 2003, M = N << 1;

int n, a, b;
int d[N];
int sum;
bitset <3600003> f[N];
bool ans[N][2];

int main()
{
	//freopen(".in", "r", stdin); freopen(".out", "w", stdout);
	n = gi <int> (), a = gi <int> (), b = gi <int> ();
	f[0][0] = 1;
	for (int i = 1; i <= n; i+=1)
		d[i] = gi <int> (), sum += d[i], f[i] = f[i - 1] | (f[i - 1] << d[i]);
	int x = a + b, y = a - b;
	if (x < -sum || x > sum || y < -sum || y > sum || ((sum - x) & 1) || ((sum - y) & 1)) return puts("No"), 0;
	x = sum - x, y = sum - y;
	x >>= 1, y >>= 1;
	if (!f[n][x] || !f[n][y]) return puts("No"), 0;
	int tmpx = x, tmpy = y;
	for (int i = n; i >= 1; i-=1)
	{
		if (tmpx >= d[i] && f[i - 1][tmpx - d[i]]) ans[i][0] = false, tmpx -= d[i];
		else ans[i][0] = true;
		if (tmpy >= d[i] && f[i - 1][tmpy - d[i]]) ans[i][1] = false, tmpy -= d[i];
		else ans[i][1] = true;
	}
	puts("Yes");
	for (int i = 1; i <= n; i+=1)
		if (ans[i][0])
		{
			if (ans[i][1]) cout << 'R';
			else cout << 'U';
		}
		else
		{
			if (ans[i][1]) cout << 'D';
			else cout << 'L';
		}
	return !!0;
}

启发:

  • 看到曼哈顿距离,马上考虑转成切比雪夫距离,这样可以将两维问题独立。
  • 要有一定的推式子能力。

标签:le,sequence,int,题解,sum,Jumping,ans,gi,define
来源: https://www.cnblogs.com/xsl19/p/abc221g.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有