标签:star 情况 input 分解质因数 amp strong inf 数据 最大
Input
Output
Sample Input
5
1 6 4 2 8
Sample Output
3
Hint
分析
Code
#include <bits/stdc++.h>
const int maxn=105,maxp=17,Inf=0x3f3f3f3f;
int prime[] = {0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53}; // 16 primes
int n,a[maxn];
int dp[maxp][1<<maxp];
int status[maxn];
void Init(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",a+i);
std::sort(a+1,a+n+1,std::greater<int>());
memset(status,0,sizeof(status));
for(int i=1;i<=58;i++)
for(int j=1;j<=16;j++)
if(i<prime[j]) break;
else if(i%prime[j]==0)//分解质因数
status[i]|=(1<<j-1);//i的质因数情况
}
void Solve(){
memset(dp,0x3f,sizeof(dp));
dp[0][0]=0;
for(int i=1;i<=std::min(n,16);i++)//最多处理最大的16个
for(int S=0;S<(1<<16);S++) //枚举上一个状态
for(int num=1;num<=58;num++)//枚举每一个可能的B[i]
if(!(status[num]&S)){//状态S中没有num的质因子
int s=S|status[num];//num的质因数都并入下一个状态
dp[i][s]=std::min(dp[i][s],dp[i-1][S]+abs(a[i]-num));
}
int ans=Inf;
for(int S=0;S<(1<<16);S++)//枚举左后一行的所有状态
ans=std::min(ans,dp[std::min(n,16)][S]);
if(n>16)//剩下的均选1
for(int i=17;i<=n;i++)
ans+=abs(a[i]-1);
printf("%d\n",ans);
}
int main(){
Init();
Solve();
return 0;
}
标签:star 情况 input 分解质因数 amp strong inf 数据 最大
原文地址:https://www.cnblogs.com/hbhszxyb/p/13254009.html