Codeforces Round #259 (Div. 1) B. Little Pony and Harmony Chest(状压dp)

来源:互联网 发布:编曲软件 好坏 编辑:程序博客网 时间:2024/05/14 17:18

Princess Twilight went to Celestia and Luna's old castle to research the chest from the Elements of Harmony.

A sequence of positive integers bi is harmony if and only if for every two elements of the sequence their greatest common divisor equals 1. According to an ancient book, the key of the chest is a harmony sequence bi which minimizes the following expression:

You are given sequence ai, help Princess Twilight to find the key.

Input

The first line contains an integer n (1 ≤ n ≤ 100) — the number of elements of the sequences a and b. The next line contains n integersa1, a2, ..., an (1 ≤ ai ≤ 30).

Output

Output the key — sequence bi that minimizes the sum described above. If there are multiple optimal sequences, you can output any of them.

Examples
input
51 1 1 1 1
output
1 1 1 1 1 
input
51 6 4 2 8
output

1 5 3 1 8


题意略。


分析:数据范围很小,我首先尝试了模拟退火,然后惨挂,接下来考虑状压dp的做法,因为ai都小于31,所以我们可以考虑状压每个数的素因数,bi一定都小于60,我们把60以内的所有数的素因数都先预处理出来,然后f[i][j]表示当前第i个数且b中前i个数的素因数状态和为j的最小花费,然后我们就可以每次枚举下一个bi+1来转移了。


#include<iostream>#include<string>#include<algorithm>#include<cstdlib>#include<cstdio>#include<set>#include<map>#include<vector>#include<cstring>#include<stack>#include<queue>#define INF 2147483640#define eps 1e-9#define MAXN 0x3f#define N 105using namespace std;int n,ans,cans,cans2,cho,c[N],use[N],a[N],b[N],choice[N][65536],f[N][65536];int dfs(int x){int ans = 0;for(int i = 2;i <= sqrt(x)+1;i++) if(x % i == 0) { while(x % i == 0) x/=i; ans += 1<<(c[i]-1); }if(x != 1) ans += 1<<(c[x]-1);return ans;}int main(){memset(f,MAXN,sizeof(f));ans = INF;c[2] = 1,c[3] = 2,c[5] = 3,c[7] = 4,c[11] = 5,c[13] = 6;c[17] = 7,c[19] = 8,c[23] = 9,c[29] = 10,c[31] = 11;c[37] = 12,c[41] = 13,c[43] = 14,c[47] = 15,c[53] = 16;for(int i = 2;i <= 58;i++) use[i] = dfs(i);cin>>n;for(int i = 1;i <= n;i++) cin>>a[i];f[0][0] = 0;for(int i = 0;i < n;i++) for(int j = 0;j <= 65535;j++)  if(f[i][j] <= n*60)   for(int k = 1;k <= 58;k++)    if((use[k] & j) == 0)     {      if(f[i+1][j + use[k]] > f[i][j] + abs(a[i+1] - k))   {       f[i+1][j + use[k]] = f[i][j] + abs(a[i+1] - k);choice[i+1][j + use[k]] =  k;       }    }for(int i = 0;i <= 65535;i++) if(ans > f[n][i]) { ans = f[n][i]; cans = i; }for(int i = n;i;i--){b[i] = choice[i][cans];cans -= use[b[i]];}for(int i = 1;i <= n;i++) cout<<b[i]<<" ";}


0 0