对于这种找互质的数的集合的题,一般是讨论每个数的质因子会不会有重复。
听说这种互质的题把质因子分为小于 \(\sqrt{n}\) 和大于 \(\sqrt{n}\) 是经典套路?
因为当 \(n\) 很小的时候,小于 \(\sqrt{n}\) 的质数并不多。比如对于这一题,小于 \(\sqrt{N=1000}\) 的数只有 \(11\) 个。
那么对于那些只有小于 \(\sqrt{N}\) 的质因子的数进行状压 dp,设 \(dp(i,j)\) 为前 \(i\) 个数中,所有选出的数的所有质因子的状态为 \(j\)(只考虑小于 \(\sqrt N\) 的质因子)。
\(j\) 的定义:如果选出的数的所有质因子中出现了第 \(k\) 个质数,那么把 \(j\) 在二进制下的第 \(k\) 位设为 \(1\),否则为 \(0\)。
例如,如果出现了 \(2\)(第 \(1\) 个质数)、\(5\)(第 \(3\) 个质数)和 \(7\)(第 \(4\) 个质数的话),\(j\) 就应该是 \((1101)_2\)。
那么假设 \(dp(i-1)\) 都已经计算完毕,现在要计算 \(dp(i,j|sta[i])\),其中 \(j\) 是某个状态,\(sta[i]\) 是 \(i\) 的质因子状态。那么现在考虑的是状态 \(j|sta[i]\)。
-
\(dp(i,j|sta[i])=dp(i-1,j|sta[i])\)。意思就是前 \(i-1\) 个数中已经选出了状态 \(j|sta[i]\),那么数 \(i\) 肯定不能在加入这个方案内(不然不互质),所以选的数不增不减。
-
\(dp(i,j|sta[i])=dp(i-1,j+1-(maxp_i>11))\)。意思就是前 \(i-1\) 个数中已经选出了状态 \(j\),那么现在肯定可以加入数 \(i\)。但是由于我们这里只考虑加入质因子都小于 \(\sqrt{N}\) 的情况,所以要减去一个 \(maxp_i>11\)。
现在对只有小于 \(\sqrt{N}\) 的质因子的数都处理完了,那么对于含有大于 \(\sqrt{N}\) 的质因子的数怎么处理呢?(不妨设所有大于 \(\sqrt{N}\) 小于 \(N\) 的质数有 \(m\) 个)
不难发现,这些数恰好仅含有一个大于 \(\sqrt{N}\) 的质因子。所以我们至少要选 \(m\) 个数才能保证是“极大方案”。又因为要保证选的数最少,所以要恰好选 \(m\) 个就行了。
最后可以把 \(1\) 也取上。
代码:
#include<bits/stdc++.h>
#define N 1010
#define INF 0x7fffffff
using namespace std;
int t,n,k;
int cnt,prime[N],maxp[N],sta[N];
int dp[2][1<<12];
bool notprime[N];
void init()
{
for(int i=2;i<=1000;i++)
{
if(!notprime[i])
{
prime[++cnt]=i;
maxp[i]=cnt;
sta[i]=(cnt<=11?(1<<(cnt-1)):0);
}
for(int j=1;j<=cnt&&i*prime[j]<=1000;j++)
{
int v=i*prime[j];
notprime[v]=true;
maxp[v]=max(maxp[i],j);
sta[v]=sta[i]|(j<=11?(1<<(j-1)):0);
}
}
}
int main()
{
init();
scanf("%d",&t);
for(int T=1;T<=t;T++)
{
scanf("%d%d",&n,&k);
int m=1;
while(prime[m]<=n) m++;
m--;
int tmp=max(0,m-11);
m=min(m,11);
int mpow=(1<<m);
for(int i=0;i<mpow;i++) dp[0][i]=INF;
dp[0][0]=0;
int now=1;
for(int i=1;i<=n;i++,now^=1)
{
for(int j=0;j<mpow;j++) dp[now][j]=dp[now^1][j];
if(i==k) continue;
for(int j=0;j<mpow;j++)
if(!(j&sta[i])&&dp[now^1][j]!=INF)
dp[now][j|sta[i]]=min(dp[now^1][j|sta[i]],dp[now^1][j]+1-(maxp[i]>11));
}
printf("Case #%d: %d\n",T,dp[now^1][mpow-1]+tmp+(k!=1));
}
return 0;
}
标签:小于,sta,分块,质数,sqrt,因子,dp,51Nod1386
From: https://www.cnblogs.com/ez-lcw/p/16837046.html