Kick Start 2019 Round H. Elevanagram
设共有 $N = \sum_{i=1}^{9} A_i$ 个数字。先把 $N$ 个数字任意分成两组 $A$ 和 $B$,$A$ 中有 $N_A = \floor{N/2}$ 个数字,$B$ 中有 $N_B=\ceil{N/2}$ 个数字。将 $A$ 中数字之和记作 $S_A$,$B$ 中数字之和记作 $S_B$。若 $(S_A - S_B) \bmod 11 \ne 0$,再进行调整。
考虑通过交换 $A$、$B$ 中的数字来改变 $S_A - S_B$ 的值。若有解一定能通过若干次交换操作使得 $S_A - S_B \bmod 11 = 0$。用 $(a, b)$ 表示将 $A$ 中的数字 $a$ 与 $B$ 中的数字 $b$ 进行交换,交换 $a, b$ 之后 $S_A - S_B$ 的变化量是 $-2(a - b)$。
注意到若存在两个数字 $i, j$ 都出现了至少 $10$ 次,则答案一定是 YES。因为当 $k$ 取遍 $1$ 到 $10$,$2k(i - j)$ 也取遍 $1$ 到 $10$(在模 $11$ 的意义下)。
若每个数字都出现了不到 $10$ 次,可以用 DP 解决。令 $f[i][j][k]$ 表示从 $A$ 中取出 $1, 2, \dots, i$ 这 $i$ 种数字共 $j$ 个且取出的数字之和模 $11$ 等于 $k$ 是否有可能。对 $B$ 也进行同样的 DP。
补充:看了官方题解之后发现这个 DP 不必分别对 $A$ 做一次再对 $B$ 做一次。可以只对 $A$ 做一次 DP,方法是把 DP 的第三维改成前 $i$ 个数字造成的差值模 $11$ 等于 $k$。如此定义 DP 状态,最后答案就是 $f[9][\floor{N/2}][0]$。下面的 DP 也可以如此改造。
考虑只有一个数字出现了至少 $10$ 次的情形。设此数字是 $d$。设 $d$ 在 $A$ 中出现了 $d_A$ 次,在 $B$ 中出现了 $d_B$ 次。
可以证明任意操作序列 $(a_1, b_1), \dots, (a_n, b_n)$ 都可以化成等价的操作序列 $(a'_1, b'_1), \dots, (a'_k, b'_k)$ 且满足对于任意 $1 \le i, j \le k$,$a'_i \ne b'_j$。
由于一定存在 $d$ 只作为 $a_i$ 或只作为 $b_i$ 的操作序列,我们只需考虑长度不超过 $t = \max\{N_A - d_A, N_B - d_B\}$ 的操作序列。于是我们可以将 $A$、$B$ 中 $1$ 到 $9$ 的每个数字取出至多 $t$ 个,对这两组数目较少的数字进行 DP。
int main() {
int T;
scan(T);
rep (T) {
kase();
vi a(10);
up (i, 1, 9) scan(a[i]);
int n10 = 0; //出现次数大于等于10的数字的个数
up (i, 1, 9) {
n10 += a[i] >= 10;
}
if (n10 >= 2) {
println("YES");
continue;
}
ll n = accumulate(all(a), 0LL);
ll m = n / 2;
vi b(10);
// 先随机分配,再通过DP判断能否进行调整。
up (i, 1, 9) {
if (a[i] < m) {
swap(a[i], b[i]);
m -= b[i];
} else {
b[i] = (int)m;
a[i] -= (int)m;
break;
}
}
ll sa = 0, sb = 0;
up (i, 1, 9) {
sa += a[i] * i;
sb += b[i] * i;
}
ll r = (sa - sb) % 11;
if (r == 0) {
println("YES");
continue;
}
if (r < 0) {
r += 11;
}
// r = r / 2;
// (11 + 1) / 2 是 2 在模 11 下的拟元。
r = r * (11 + 1) / 2 % 11;
// dp[i][j][k] 在前i种数里选择j个数余数是否可能是k
// 用滚动数组去掉dp数组第一维。
int na = 0, nb = 0;
up (i, 1, 9) {
if (a[i] < 10) {
na += a[i];
}
if (b[i] < 10) {
nb += b[i];
}
}
auto t = max(na, nb);
up (i, 1, 9) {
a[i] = min(a[i], t);
b[i] = min(b[i], t);
}
na = accumulate(all(a), 0);
nb = accumulate(all(b), 0);
vv<int> A(na + 1, vi(11));
vv<int> B(nb + 1, vi(11));
A[0][0] = 1;
B[0][0] = 1;
int ca = 0, cb = 0;
up (i, 1, 9) {
if (a[i] > 0) {
down (j, ca, 0) {
rng (k, 0, 11) {
if (A[j][k]) {
up (l, 1, a[i]) {
A[j + l][(k + l * i) % 11] = true;
}
}
}
}
ca += a[i];
}
if (b[i] > 0) {
down (j, cb, 0) {
rng (k, 0, 11) {
if (B[j][k]) {
up (l, 1, b[i]) {
B[j + l][(k + l * i) % 11] = true;
}
}
}
}
cb += b[i];
}
}
bool flag = false;
up (i, 1, min(na, nb)) {
rng (j, 0, 11) {
if (B[i][j] && A[i][(j + r) % 11]) {
flag = true;
break;
}
}
if (flag) break;
}
println(flag ? "YES" : "NO");
}
return 0;
}
Kick Start 2019 Round H. Elevanagram的更多相关文章
- kick start 2019 round D T3题解
---恢复内容开始--- 题目大意:共有N个房子,每个房子都有各自的坐标X[i],占据每个房子需要一定花费C[i].现在需要选择K个房子作为仓库,1个房子作为商店(与题目不同,概念一样),由于仓库到房 ...
- kick start 2019 round D T2题解
题目大意:由N个房子围成一个环,G个人分别顺时针/逆时针在房子上走,一共走M分钟,每分钟结束,每个人顺/逆时针走到相邻的房子.对于每个房子都会记录最后时刻到达的人(可能是一群人).最终输出每个人会被几 ...
- Kick Start 2019 Round A Contention
$\DeclareMathOperator*{\argmax}{arg\,max}$ 题目链接 题目大意 一排 $N$ 个座位,从左到右编号 $1$ 到 $N$ . 有 $Q$ 个预定座位的请求,第 ...
- Kick Start 2019 Round A Parcels
题目大意 $R \times C$ 的网格,格子间的距离取曼哈顿距离.有些格子是邮局.现在可以把至多一个不是邮局的格子变成邮局,问每个格子到最近的邮局的曼哈顿距离的最大值最小是多少. 数据范围 $ 1 ...
- Kick Start 2019 Round B Energy Stones
对我很有启发的一道题. 这道题的解法中最有思维难度的 observation 是 For simplicity, we will assume that we never eat a stone wi ...
- 【DP 好题】Kick Start 2019 Round C Catch Some
题目链接 题目大意 在一条数轴上住着 $N$ 条狗和一个动物研究者 Bundle.Bundle 的坐标是 0,狗的坐标都是正整数,可能有多条狗住在同一个位置.每条狗都有一个颜色.Bundle 需要观测 ...
- Kick Start 2019 Round F Teach Me
题目链接 题目大意 有 $N$ 个人,$S$ 项技能,这些技能用 $1, 2, 3, \dots, S$ 表示 .第 $i$ 个人会 $c_i$ 项技能($ 1 \le c_i \le 5 $).对于 ...
- Kick Start 2019 Round D
X or What? 符号约定: $\xor$ 表示异或. popcount($x$) 表示非负整数 $x$ 的二进制表示里数字 1 出现的次数.例如,$13 = 1101_2$,则 popcount ...
- Google Kick Start 2019 C轮 第一题 Wiggle Walk 题解
Google Kick Start 2019 C轮 第一题 Wiggle Walk 题解 题目地址:https://codingcompetitions.withgoogle.com/kickstar ...
随机推荐
- HZWER
我们的征途是星辰大海 2016年3月13日8,8077 尊敬的各位老师.亲爱的同学们: 大家好,我是高三(1)班的黄哲威.今天很荣幸能和大家分享一些有关竞赛的心得体会. 去年7月15日,第32届全国信 ...
- Centos7安装Redis5.0.3
1.切换目录 cd tmp 2.下载 wget http://download.redis.io/releases/redis-5.0.3.tar.gz 3.解压,删除压缩包 tar xzf redi ...
- jQuery的$符号
jQuery使用$的原因是: 书写简洁, 相对于其他字符与众不同, 容易被记住. JQuery占用了两个变量: $ 和 jQuery. 当在代码中打印 $ 和 jQuery时: <script ...
- Java中String、StringBuffer、StringBuilder
String 对象 String 创建机制 String 是 Java 语言中非常基础和重要的类,提供了构造和管理字符串的各种基本逻辑,由源码可知,它是典型的 Immutable (不可变)类,被fi ...
- LG5283 异或粽子
题意 共有\(n\)个数,选择\(k\)个不同的\([l,r]\)区间,使得它们的异或和最大 $ 1 \leq n \leq 5 \times 10^5,k \leq 2 \times 10^5$ 思 ...
- 反省——关于csp-s模拟50
本人于搜索csp-s模拟49题解时,有意识地点开了一篇关于csp-s模拟50T2的题解,并知道了题解是二维前缀和以及四维偏序. 更重要的是,那篇博客说有解法二,叫二维莫队. 于是我上网搜索二维莫队,结 ...
- 教你快速写一个EventBus框架
前言EventBus相信大多数人都用过,其具有方便灵活.解耦性强.体积小.简单易用等优点,虽然现在也有很多优秀的替代方案如RxBus.LiveDataBus等,但不可否认EventBus开创了消息总线 ...
- Mybatis传递多个参数进行SQL查询的用法
当只向xxxMapper.xml文件中传递一个参数时,可以简单的用“_parameter”来接收xxxMapper.java传递进来的参数,并代入查询. 但是,如果在xxxMapper.java文件中 ...
- RabbitMQ学习之:(七)Fanout Exchange (转贴+我的评论)
From:http://lostechies.com/derekgreer/2012/05/16/rabbitmq-for-windows-fanout-exchanges/ PunCha: Ther ...
- AngularJS 指令(Directivce )一
指令(Directive),是AngularJS中一块比较重要的内容,在实践中,我们提倡将控制器(Controller)写得短小精悍,逻辑代码尽量少,要实现这种目的,我们主要通过将逻辑代码抽取到服务( ...