首页 > 其他分享 >AtCoder Regular Contest 114 D Moving Pieces on Line

AtCoder Regular Contest 114 D Moving Pieces on Line

时间:2023-04-21 22:57:25浏览次数:40  
标签:AtCoder typedef 匹配 Contest long Pieces 红点

洛谷传送门

AtCoder 传送门

挺有意思的题。

首先显然地,一个棋子不会走回头路。于是一个棋子沿着边走的效果就是区间异或。

更进一步,设 \(s_i\) 为 \(i-1 \to i\) 的边颜色与 \(i \to i+1\) 的边颜色是否相同(差分),相当于对于每个 \(i\) 都选择 \(s_{a_i}\) 和 \(s_{x_i}\),将它们异或上 \(1\)(\(x_i\) 任选),代价为 \(|a_i - x_i|\),最后要求恰好 \(k\) 个位置 \(t_1,t_2,...,t_k\) 为 \(1\),求最小代价。

\(s_{a_i}\) 的异或操作可以事先处理。操作后需要被 \(x_i\) 异或奇数次的位置可知。现在问题又变成了,数轴上有 \(n\) 个红点 \(a_1,a_2,...,a_n\) 和 \(m\) 个蓝点 \(b_1,b_2,...,b_m\),红点和红点可以匹配(随便选一个它们之间的点互相抵消),红点和黑点也可以匹配,要求每个黑点和每个红点都要被匹配,每对匹配的价值是坐标之差的绝对值,求最小代价。

考虑 \(n = m\) 怎么做。这个是个经典问题,\(a\) 和 \(b\) 排序后每对匹配相交一定不优,于是答案就是排序后 \(ans = \sum\limits_{i=1}^n |a_i - b_i|\)。

现在 \(n > m\)(如果 \(n < m\) 就无解),不妨沿用 \(n = m\) 时的结论。不难得出两个红点仅当它们在红点之中相邻才能形成匹配。发现数据范围允许 \(O(nm)\),大力 dp,设 \(f_{i,j}\) 为排序后前 \(i\) 个红点和前 \(j\) 个蓝点都能匹配的代价最小值。有转移:

\[f_{i,j} \gets \min(f_{i-1,j-1} + |a_i - b_j|, f_{i-2,j} + a_i - a_{i-1}) \]

答案为 \(f_{n,m}\)。

code
// Problem: D - Moving Pieces on Line
// Contest: AtCoder - AtCoder Regular Contest 114
// URL: https://atcoder.jp/contests/arc114/tasks/arc114_d
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 5050;

ll n, m, a[maxn], b[maxn << 1], c[maxn], f[maxn][maxn];

void solve() {
	scanf("%lld%lld", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", &a[i]);
		b[i] = a[i];
	}
	for (int i = n + 1; i <= n + m; ++i) {
		scanf("%lld", &b[i]);
	}
	m += n;
	sort(a + 1, a + n + 1);
	sort(b + 1, b + m + 1);
	int tot = 0;
	for (int i = 1, j = 1; i <= m; i = (++j)) {
		while (j < m && b[j + 1] == b[i]) {
			++j;
		}
		if ((j - i + 1) & 1) {
			c[++tot] = b[i];
		}
	}
	m = tot;
	if (n < m) {
		puts("-1");
		return;
	}
	mems(f, 0x3f);
	f[0][0] = 0;
	for (int i = 1; i <= n; ++i) {
		for (int j = 0; j <= m; ++j) {
			f[i][j] = f[i - 1][j - 1] + abs(a[i] - c[j]);
			if (i >= 2) {
				f[i][j] = min(f[i][j], f[i - 2][j] + a[i] - a[i - 1]);
			}
		}
	}
	printf("%lld\n", f[n][m]);
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:AtCoder,typedef,匹配,Contest,long,Pieces,红点
From: https://www.cnblogs.com/zltzlt-blog/p/17342104.html

相关文章

  • 模拟赛 & VP & Contest 记录
    CatOJC140(初中)\(100+93+100+10=303\),Rank1。是个dp场,A题期望dp,B题神奇猜结论,C题换根dp,D题树上博弈dp。A题设\(f_u\)为填满子树\(u\)的期望次数,\(s_u\)为\(u\)子树大小,容易得到\(f_u=f_v+\frac{1}{s_u}\)。B题若\(n\)是偶数,考虑数列里随便取一个数将其......
  • Atcoder Beginner Contest 298---E
    题目:E-UnfairSugoroku(atcoder.jp)分析:这题状态转移方程挺好推的,但是用dp解是我没想到的dp[i][j][0]表示T在i点,A在j点且轮到T走时赢的概率dp[i][j][1]表示T在i点,A在j点且轮到A走时赢的概率代码:#include<bits/stdc++.h>usingnamespacestd;#definelllonglong#def......
  • AtCoder Regular Contest 109 F 1D Kingdom Builder
    洛谷传送门AtCoder传送门考虑判断一个终止态是否可达。如果只有一个棋子连续段那一定可达;否则就存在\(\ge2\)个连续段。此时把放棋子看成删除,那么限制就是如果删除一个孤立的棋子(两边没有棋子)且还有别的格子有棋子,这个棋子的颜色异于其他连续段的两边棋子的颜色。设第一......
  • AtCoder Beginner Contest 298
    A-JobInterview#include<bits/stdc++.h>usingnamespacestd;intmain(){ intn; strings; cin>>n>>s; if(s.find("x")!=-1){ printf("No\n"); }elseif(s.find("o")==-1){ printf("No......
  • Atcoder Regular Contest 118 E - Avoid Permutations(容斥+DP)
    挺套路的DP。第一步是显然的:转换贡献体,DP一条从\((0,0)\)到\((n+1,n+1)\)的路径,然后计算有多少个排列满足这条路径不经过任何一个\((i,p_i)\)。正着统计肯定不好求,考虑容斥。即我们钦定一些路径上的点,满足这些点必须对应某个\((i,p_i)\),然后计算有多少个\(p\)符合这个......
  • Contest 23-04-18
    #D.糖果镇思路\(m=3\)时整个路径有两个拐点,分别是\(m=1\tom=2,m=2\tom=3\)设拐点\(1\)在第\(i\)列,拐点\(2\)在第\(j\)列,则路径上的数字总和为\((front[1][i])+(front[2][j]-front[2][i-1])+(back[j])\)(\(front[i][j]\)表示第i行\(1\toj\)的前缀和,\(back[j]\)表......
  • AtCoder Regular Contest 109 E 1D Reversi Builder
    洛谷传送门AtCoder传送门考虑固定\(s\)和每个格子的颜色,最终有多少个石子被染黑。结论:任何时刻只有不多于两个极大同色连通块。证明:设\([x,y]\)为当前的黑连通块,\([y+1,z]\)为白连通块。如果下一次染\(x-1\),若\(x-1\)为白,则\([x-1,z]\)都被染为白;否则\(x-1\)被......
  • AtCoder Regular Contest 109 D L
    洛谷传送门AtCoder传送门这种题根本做不出来……考虑一个L形怎么方便地表示出来。可以发现对于组成L形的三个点\((x_1,y_1),(x_2,y_2),(x_3,y_3)\),只要知道\(x=x_1+x_2+x_3\)和\(y=y_1+y_2+y_3\),就能确定三个坐标。证明是设折点坐标为\((p,q)\),则其余两......
  • AtCoder Regular Contest 106 F Figures
    洛谷传送门AtCoder传送门晚自习的时候胡出来的做法(((首先你会发现题目等价于求\(\sum\limits_{(\sum\limits_{i=1}^na_i)=2(n-1)\land\foralli\in[1,n],1\lea_i\led_i}\prod\limits_{i=1}^n\dfrac{d_i!}{(d_i-a_i)!}\)。翻译一下就是枚举每个点的度数\(a_i\)......
  • ABC297F AtCoder Beginner Contest 297 F - Minimum Bounding Box 2
    https://atcoder.jp/contests/abc297/tasks/abc297_f在\(n\timesm\)的棋盘上放置\(k\)个棋子,记矩形A为能覆盖所有\(k\)个棋子的最小的矩形,求A的面积的期望将问题反过来考虑,枚举每种矩形有多少种放置棋子的方案,对于一个\(n\timesm\)的矩形,我们可以用容斥的方法......