Codeforces Round #259 (div2) D Problem Solving report,
D. Little Pony and Harmony Chesttime limit per test4 secondsmemory limit per test256 megabytesinputstandard inputoutputstandard output
Princess Twilight went to Celestia and Luna's old castle to research the chest from the Elements of Harmony.
A sequence of positive integersBIIs harmony if and only if for every two elements of the sequence their greatest common divisor equals 1. According to an existing ent book, the key of the chest is a harmony sequenceBIWhich minimizes the following expression:
You are given sequenceAI, Help Princess Twilight to find the key.
Input
The first line contains an integerN(1 digit ≤ DigitNLimit ≤ limit 100)-the number of elements of the sequencesAAndB. The next line containsNIntegersA1, bytes,A2, middle..., middle ,...,AN(1 digit ≤ DigitAILimit ≤ Limit 30 ).
Output
Output the key-sequenceBIThat minimizes the sum described above. If there are multiple optimal sequences, you can output any of them.
Sample test (s) input
51 1 1 1 1
Output
1 1 1 1 1
Input
51 6 4 2 8
Output
1 5 3 1 8
Question:
Give N ai numbers and find another sequence of bi, which requires sum | ai-bi |, which is the shortest and all bi are of mutual quality.
Solution:
Here, the question gives a few conspicuous conditions. ai is limited to 1 ~ Between 30, because you can select 1 for bi without limit, then | ai-bi | maximum is 29, meaning bi <59.
The mutual quality of all bi is required. The quality factors decomposed by all bi are different. bi <59 has 16 prime numbers. Here we can easily think of the State compressed DP.
Use s to indicate the state of the prime factor used in the current phase. For example, s = 3 = 11 indicates that the first and second prime factors are used in the current state.
Soon we can write the state transition equation:
F [I] [s] = min (f [I-1] [s ^ c [k] + abs (a [I]-k )). C [k] indicates the prime factor used by the number k.
Code:
#include <cstdio>#include <cmath>#include <cstring>#define M_max 60#define N_max 123#define inf 0x3f3f3f3fusing namespace std;int p[N_max], c[M_max], a[N_max];int f[N_max][1<<16], pre[N_max][1<<16][2];int n, cnt, minnum, minpos;void prime() {for (int i = 2; i <= M_max; i++) {bool flag = false;for (int j = 2; j <= sqrt(i); j++)if (i%j == 0) {flag = true;break;}if (!flag) p[++cnt] = i;}for (int i = 1; i <= M_max; i++)for (int j = 1; j <= cnt; j++)if (i%p[j] == 0)c[i] |= 1 << (j-1);}void init() {prime();scanf("%d", &n);for (int i = 1; i <= n; i++) scanf("%d", &a[i]);}void print(int x, int pos) {if (x == 0) return;print(x-1, pre[x][pos][0]);printf("%d ", pre[x][pos][1]);}void solve() {memset(f, inf, sizeof(f));memset(f[0], 0, sizeof(f[0]));minnum = inf;for (int i = 1; i <= n; i++)for (int s = 0; s < (1<<16); s++)for (int k = 1; k <= M_max; k++)if ((s&c[k]) == c[k]) {int tmp = f[i-1][s^c[k]] + abs(a[i]-k);if (tmp < f[i][s]) {f[i][s] = tmp;pre[i][s][0] = s^c[k];pre[i][s][1] = k;}}for (int s = 0; s < (1<<16); s++)if (f[n][s] < minnum) {minnum = f[n][s];minpos = s;}print(n, minpos);}int main() {init();solve();}