题目大意:
cf div1 B:简单分析一波即可。
#include <bits/stdc++.h>
using namespace std;
const int N=105;
int n,max_statue,ans,now;
const int prime[16]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
int a[N],add[N],f[N][1<<16];
void dfs(int p,int ans,int n)
{
for (register int i=1; i<=58; ++i)
{
if (((add[i]&p)==add[i]) && f[n-1][p^add[i]]+abs(a[n]-i)==f[n][p])
{
dfs(p^add[i],f[n-1][p^add[i]],n-1);
printf("%d ",i);
break;
}
}
}
int main(){
scanf("%d",&n);
for (register int i=1; i<=n; ++i) scanf("%d",&a[i]);
for (register int i=1; i<=58; ++i)
{
for (register int j=0; j<16; ++j) if (i%prime[j]==0) add[i]|=1<<j;
}
max_statue=(1<<16)-1;
memset(f,60,sizeof(f));
for (register int p=0; p<=max_statue; ++p) f[0][p]=0;
for (register int i=1; i<=58; ++i) f[1][add[i]]=min(f[1][add[i]],abs(i-a[1]));
for (register int i=1; i<n; ++i)
{
for (register int p=0; p<=max_statue; ++p)
for (register int j=1; j<=58; ++j)
if (!(add[j]&p))
{
f[i+1][p|add[j]]=min(f[i+1][p|add[j]],f[i][p]+abs(j-a[i+1]));
}
}
ans=2e9;
for (register int p=0; p<=max_statue; ++p) if (f[n][p]<ans) ans=f[n][p],now=p;
dfs(now,ans,n);
return 0;
}