Little Pony and Harmony Chest
经典状态压缩dp
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #define min(x,y) (x>y?y:x) using namespace std; int factor[30],all,n,a[105],b[105][1<<17],pre[105][1<<17],s1,s0,f[105][1<<17],ansk; bool pd[80]; void print(int i,int k) { if(i==0) return; print(i-1,pre[i][k]); if(i==n) printf("%d",b[i][k]); else printf("%d ",b[i][k]); return; } int main() { pd[1]=1; for(int i=2; i<=60; i++) if(!pd[i]){ factor[++all]=i; for(int j=2; i*j<=60; j++) pd[i*j]=1; } scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d",&a[i]); memset(f,127,sizeof(f)); for(int i=0; i<=(1<<16)-1; i++) f[0][i]=0; int ans=10000000; for(int i=1; i<=n; i++) for(int j=1; j<=59; j++) { s1=(1<<16)-1; for(int k=1; k<17; k++) if(j%factor[k]==0) s1=s1^(1<<(k-1)); s0=s1^((1<<16)-1); for(int k=0; k<=(1<<16)-1; k++) { int p0=k&s1,p1=(k&s1)+s0; if(f[i][p1]>f[i-1][p0]+abs(a[i]-j)) { f[i][p1]=f[i-1][p0]+abs(a[i]-j); b[i][p1]=j; pre[i][p1]=p0; } if(i==n&&ans>f[n][p1]) { ans=f[n][p1]; ansk=p1; } } } print(n,ansk); return 0; }