luogu P4161 [SCOI2009]游戏
我们发现整个大置换中,会由若干形如(a1→a2,a2→a3,...an−1→an,an→a1)的循环置换组成,记某个循环置换中元素个数为mi而整个置换的循环节大小为lcm(m1,m2,...),那么问题转化成把一个数n拆成若干整数之和,问拆出来的整数的lcm有多少种
把[1,n]的质数筛出来,然后dfs,从前往后考虑质数pi,每次从剩余的数中减去pik,假设某个时刻表示的数为s,那么减去pik后就能表示s∗pik,这样子计算是不重不漏的,但是无法通过此题(方案数为long long级别)
考虑dp,设fi为n=i时的答案,然后依次枚举质数,因为当前考虑的质数之前没考虑,所以fi可以从fi−pj,fi−pj2,fi−pj3...转移过来,这其实就是个背包
详见代码
#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define db double
#define eps (1e-5)
using namespace std;
il LL rd()
{
LL x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int prm[200],tt,n;
char vis[1010];
il void init()
{
for(int i=2;i<=n;i++)
{
if(!vis[i]) prm[++tt]=i;
for(int j=1;j<=tt&&i*prm[j]<=n;j++)
{
vis[i*prm[j]]=true;
if(i%prm[j]==0) break;
}
}
}
LL f[1010];
/*void dfs(int o,int s)
{
if(o>tt||s<prm[o]) return;
dfs(o+1,s);
int xx=prm[o];
while(s>=xx)
{
++ans;
dfs(o+1,s-xx);
xx*=prm[o];
}
}*/
int main()
{
n=rd();
init();
for(int i=0;i<=n;i++) f[i]=1;
for(int i=1;i<=tt;i++)
for(int j=n;j>=0;j--)
for(int k=prm[i];j-k>=0;k*=prm[i])
f[j]+=f[j-k];
printf("%lld\n",f[n]);
return 0;
}
分类:
1-source-省选
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库