#P16307. [Ucpc2022]NPU 优化
[Ucpc2022]NPU 优化
题目描述
Furiosa AI 正在研发一种 NPU(Neural Processing Unit,神经网络处理器),以便比传统处理单元更快地完成人工智能模型的训练与推理。
在普通处理单元上运行的程序,会使用多种运算符处理存放在主机(host)中的数据,从而计算出所需结果。本题将这一过程简化为以下模型。
- 主机拥有 个数据存储位置,编号为 到 。
- 每个运算符接收一个或多个输入数据,并计算出一个输出数据。运算符的编号也在 到 之间。
- 程序使用如下 BNF(Backus-Naur Form)描述:
<number> ::= 0 | 1 | ... | 999999
<value> ::= <number> | <number>(<list>)
<list> ::= <value> | <list>,<value>
- 一个程序计算一个值,因此整个程序是一个符合
<value>的字符串。 <value>的值按如下方式定义:- 若
<value>表示为<number>,则其值是程序开始前主机的<number>号位置中存放的数据。 - 若
<value>表示为<number>(<list>),则依次以<list>中各个<value>的值为输入,调用编号为<number>的运算符,其输出就是该<value>的值。
- 若
- 一个程序中,同一个
<number>不会出现多次。
为了让程序在 NPU 上运行,需要把它编译为 NPU 所支持的低级指令。不同的编译方式可能具有不同的内存用量和指令数。
NPU 可以存放 个数据,内存位置编号为 到 。它支持以下三种指令。
1. 从主机载入数据
a >> b
把主机中编号为 的数据复制到 NPU 内存的 号位置。
若该内存位置原本已有数据,则覆盖原数据。
2. 把数据写回主机
a << b
把 NPU 内存的 号位置中的数据复制到主机的 号位置。
若该主机位置原本已有数据,则覆盖原数据。
3. 执行运算符
o = w | m1 m2 ... ml
按顺序取出 NPU 内存位置 中的数据,作为编号为 的运算符的输入,并把输出保存到 NPU 内存位置 。
输出位置不能与任何输入位置相同,即
一个 NPU 程序是上述指令组成的序列,执行时按顺序运行所有指令。
给定一个符合 <value> 的字符串,请把它编译成一个 NPU 程序,使其计算出该 <value> 的值,并最终将结果保存在 NPU 内存位置 中。
你需要使使用的指令数量最少。
输入格式
第一行包含一个整数 ,表示 NPU 内存可存放的数据数量。
第二行包含一个符合 <value> 的字符串,表示需要计算的表达式。字符串长度不超过 。
输出格式
如果 NPU 内存不足,无法编译该程序,输出:
-1
否则,第一行输出最少指令数。
接下来逐行输出构成最优 NPU 程序的所有指令,输出顺序即执行顺序。每条指令中的相邻记号之间必须恰好用一个空格分隔。
若有多种最优答案,输出任意一种即可。
样例
样例 1
输入
7
71(72(41,42),73(43,44))
输出
7
41 >> 3
42 >> 4
43 >> 5
44 >> 6
1 = 72 | 3 4
2 = 73 | 5 6
0 = 71 | 1 2
样例 2
输入
3
71(72(41,42),73(43,44))
输出
9
43 >> 2
44 >> 0
1 = 73 | 2 0
59 << 1
41 >> 2
42 >> 0
1 = 72 | 2 0
59 >> 2
0 = 71 | 1 2
样例 3
输入
2
71(72(41,42),73(43,44))
输出
-1