[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:
根据置换的知识,易得题目等价于:
给定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; }
相关文章推荐
- 《Java疯狂讲义》中关联、组合和聚合的谬误
- Python:AttributeError: 问题
- Redis-链表类型操作
- Android源代码分析(三) MediaScanner源码分析(下)
- OJ刷题---手机尾号评分
- jpython LookupError: unknown encoding 'ms936' 问题解决
- 编写高质量代码改善C#程序的157个建议——建议143:方法抽象级别应在同一层次
- 高光和金属反射光照模型
- 用VC进行COM编程所必须掌握的理论知识
- C语言插入排序
- Mac架设Cocos2d-JS开发环境问题记录
- java新手笔记27 监听器类
- 吃煎饼思考人生:从黄太吉看商家的社会化营销
- android SIM state
- windows上使用sqllite3的链接整理
- 电子工程师必上的十大专业网站
- C# String.Format字符串中包含"{" "}"时需注意的问题
- 漫反射光照模型
- php中的转义字符
- sqllite3打开在其他文件夹里的database