2024 信友队 noip 冲刺 10.4

T1

给定 nnn 个数 {an}\{a_n\}{an},每次操作可以选择一个 i∈[1,n]i\in [1,n]i[1,n] 使得 ai←ai−1a_i\gets a_i-1aiai1。求最少操作次数使得 aaa 中除了 000 以外其他值至多出现 111 次。

n≤2×105n\le 2\times 10^5n2×105ai∈[0,106]a_i\in [0,10^6]ai[0,106]

直接在值域上考虑,令 tit_iti 表示值为 iii 的元素个数,从大往小考虑,若 ti>1t_i>1ti>1 那么需要执行 ti−1t_i-1ti1 次操作令 ti←1t_i\gets 1ti1,与此同时会令 ti−1←ti−1+ti−1t_{i-1}\gets t_{i-1}+t_i-1ti1ti1+ti1;一直这么推下去推到 000 为止即可。如果值域大一些直接考虑有值的 nnn 个位置即可。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define open(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
const int maxn = 1e6 + 5;
ll t[maxn]; int n, a[maxn];
int main() {
	open(seq); 
	scanf("%d", &n);
	for (int i = 1; i <= n; i ++)
		scanf("%d", &a[i]), t[a[i]] ++;
	ll ans = 0;
	for (int i = 1e6; i > 0; i --)
		if (t[i] > 1)
			ans += t[i] - 1, t[i - 1] += t[i] - 1;
	printf("%lld\n", ans);
	return 0;
}

T2

给定 nnn,构造一个仅包含 X,Y,D\texttt{X},\texttt{Y},\texttt{D}X,Y,D 三种字符的字符串使得 XYD\texttt{XYD}XYD 这个子序列恰好出现 nnn 次。要求串长 ≤6000\le 60006000

n≤109n\le 10^9n109

赛时糖丸了,推了一个关于平方的做法,差点就被我发现了。一个简单的做法是考虑在 X\texttt{X}X 后面放 YD\texttt{YD}YD 的贡献,发现若放了 nnn 个则产生了 n(n+1)2\cfrac{n(n+1)}{2}2n(n+1)XYD\texttt{XYD}XYD 子序列(可能往上往下有出入,大概长这样),于是我们考虑把 nnn 拆成这么几段,先放一个由若干段 YD\texttt{YD}YD 循环组成的串,然后在对应位置插入若干个 X\texttt{X}X 即可。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2005;
#define ll long long
#define open(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
ll a[maxn];
int main() {
	open(xyd);
	int n, m; scanf("%d", &n);
	for (m = 1; m <= 2000; m ++)
		if (a[m - 1] + m > n) break; 
		else a[m] = a[m - 1] + m;
	for (m --; m > 0; m --, putchar('Y'), putchar('D'))
		for (; a[m] <= n; n -= a[m]) putchar('X');
	return 0;
}

T3

给定两个长度为 nnn 的序列 x,yx,yx,y,再给定 mmm 个长度为 nnn 的序列,对于第 iii 个序列 aia_iai 选择以下操作之一进行:

  • 对于所有 j∈[1,n]j\in[1,n]j[1,n],令 xj←max⁡(xj,ai,j)x_j\gets \max(x_j,a_{i,j})xjmax(xj,ai,j)
  • 对于所有 j∈[1,n]j\in[1,n]j[1,n],令 yj←max⁡(yj,ai,j)y_j\gets \max(y_j,a_{i,j})yjmax(yj,ai,j)​。

要求按顺序操作,求操作后最大的 ∑i=1nxi+yi\sum^n_{i=1}x_i+y_ii=1nxi+yi

n≤10n\le 10n10m≤105m\le 10^5m105

先拼了一档 m≤20m\le 20m20 的暴搜做法,然后又拼了一个乱搞做法:每次比较 x,yx,yx,y 产生的增量,哪个多操作哪个,最终骗到 72pts72\mathrm{pts}72pts。然后一种可行解是随机化,正确率还挺高。

T4

显然最小的取法就是从每个集合中取一个最小值求和,我们设这个最优值为 ansansans。考虑其可能的后几个略小一些的状态。我们将每个集合按照次小值减最小值的差从小到大排序,每个集合内部按从小到大排序。假设当前状态 {i,j,w}\{i,j,w\}{i,j,w} 表示枚举到第 iii 个集合中的第 jjj 个数,考虑将 ansansans 中第 iii 个集合取的数更换为 jjj更换后的答案为 www。令 c(i,j)c(i,j)c(i,j) 表示集合 iii 中第 jjj 大的值,最初始的状态即为 {1,2,ans−c(1,1)+c(1,2)}\{1,2,ans-c(1,1)+c(1,2)\}{1,2,ansc(1,1)+c(1,2)}。对于每个状态会有三个可能的分支:

  • 如果 j<sizij<siz_ij<sizi,则一种可能的选择即为放弃更换为 jjj,考虑更换为 j+1j+1j+1。新的状态为 {i,j+1,w−c(i,j)+c(i+j)}\{i,j+1,w-c(i,j)+c(i+j)\}{i,j+1,wc(i,j)+c(i+j)}
  • 如果 iii 不是最后一个集合:
    • 一种可能的选择即为决定更换为 jjj,开始考虑 i+1i+1i+1 集合的选择。新的状态为 {i+1,2,w−c(i+1,1)+c(i+1,2)}\{i+1,2,w-c(i+1,1)+c(i+1,2)\}{i+1,2,wc(i+1,1)+c(i+1,2)}
    • 另外,如果 j=2j=2j=2,则一种可能的选择即为放弃更换 iii 中的元素,直接考虑 i+1i+1i+1 集合的选择。新的状态为 {i+1,2,w−c(i,2)+c(i,1)−c(i+1,1)+c(i+1,2)}\{i + 1,2,w - c(i,2) + c(i,1) - c(i+1,1) + c(i+1,2)\}{i+1,2,wc(i,2)+c(i,1)c(i+1,1)+c(i+1,2)}

开一个优先队列记录这些状态,从中取 kkk​ 轮即为答案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值