Codeforces 4538 (状态压缩dp)Little Pony and Harmony Chest

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;
}
原文地址:https://www.cnblogs.com/Mathics/p/3886881.html