您的位置:首页 > 其它

[BZOJ1025][SCOI2009]游戏

2015-08-23 23:42 267 查看
原题地址

根据置换的知识,易得题目等价于:

给定n,将n“拆”成数列{ai}满足Q=lcm(ai)且Σai≤n,求有多少种可能的Q,其中lcm(ai)表示数列中所有数的最小公倍数.

根据观察,又易得:

lcm(ai)=Q(Q为定值)时,当ai形如pkii(p为质数)时,Σai最小.

所以我们只需要把n“拆”成“ai形如pkii(p为质数)的数列{ai}”,即可取遍所有可能的Q.

然后易得题目等价于:

Q=Πpkii,其中pi为第i小的质数,Σpkii≤n,求所有可能的Q的个数.

然后题目就简单了,DP即可.

AC code:

#include <cstdio>
typedef long long ll;
const int N=1010;
ll   n,tot,ans;
ll   prm
;
ll   f

;
bool flag
;

int main(){
scanf("%lld",&n);
for(ll i=2;i<=n;i++){
if(!flag[i]) prm[++tot]=i;
for(ll j=1;j<=tot&&i*prm[j]<=n;j++){
flag[i*prm[j]]=1;
if(!(i%prm[j])) break;
}
}
f[0][0]=1;
for(ll i=1;i<=tot;i++){
for(ll j=0;j<=n;j++){
f[i][j]=f[i-1][j];
for(ll k=prm[i];j-k>=0;k*=prm[i])f[i][j]+=f[i-1][j-k];
}
}
for(ll i=0;i<=n;i++) ans+=f[tot][i];
printf("%lld\n",ans);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: