#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int mx = 310;
// a->第二天各商店菜价
// d[v][q][r] = 1->第一天位置p的菜价为q、位置p+1的菜价为r时满足第二天位置[p+1,n]的菜价约束
// p[v][q][r]->满足条件的最小的第v+2天的菜价, 用于路径输出
int a[mx], d[mx][mx][mx], p[mx][mx][mx];
int main(){
// M->最大可能菜价
int n, M = 0;
cin >> n;
for (int i = 1; i <= n; i++){
cin >> a[i];
M = max(M, a[i]*3);
}
// 计算第一天位置n-1的菜价为i、位置n的菜价为j时满足第二天菜价约束的d[n-1][i][j]
for (int i = 1; i <= M; i++){
for (int j = 1; j <= M; j++){
if ((i+j)/2 == a[n]){
d[n-1][i][j] = 1;
p[n-1][i][j] = 0;
}
}
}
// 状态转移, 找到满足约束条件的最小字典序路径
for (int i = n-1; i >= 2; i--){
for (int k = M; k >= 1; k--){
for (int l = M; l >= 1; l--){
if (d[i][k][l]){
for (int j = 1; j <= M; j++){
if ((j+k+l)/3 == a[i]){
d[i-1][j][k] = 1;
p[i-1][j][k] = l;
}
}
}
}
}
}
// 最小字典序路径输出
bool flag = true;
for (int i = 1; flag && i <= M; i++){
for (int j = 1; flag && j <= M; j++){
if (d[1][i][j] && (i+j)/2 == a[1]){
int l = i, r = j;
cout << l;
for (int k = 2; k <= n; k++){
cout << " " << r;
// 获取下、下个位置的菜价
int tmp = p[k-1][l][r];
l = r;
r = tmp;
}
flag = false;
}
}
}
return 0;
}
04-08
339
11-29
289