[bzoj1025][SCOI2009]游戏【dp】

【题目链接】
  http://www.lydsy.com/JudgeOnline/problem.php?id=1025
【题解】
   ans=lcm(l1..ln) a n s = l c m ( l 1 . . l n )
  其中 li l i 为每个变换的循环长度。
  接下来就可以dp了
  记 f[i][j] f [ i ] [ j ] 表示考虑了前 i i 个素数,使用了不多于j个数字的方案数。
  转移就是 f[i][j]=kf[i1][jPki]+f[i1][j] f [ i ] [ j ] = ∑ k f [ i − 1 ] [ j − P i k ] + f [ i − 1 ] [ j ]
 

/* --------------
    user Vanisher
    problem bzoj-1025
----------------*/
# include <bits/stdc++.h>
# define    ll      long long
# define    N       1010
using namespace std;
ll read(){
    ll tmp=0, fh=1; char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
    while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
    return tmp*fh;
}
ll n,f[N][N],p[N],pnum;
bool fp[N];
int main(){
    n=read();
    fp[1]=true;
    for (ll i=2; i<=n; i++)
        if (fp[i]==false){
            p[++pnum]=i;
            for (ll j=i+i; j<=n; j+=i)
                fp[j]=true;
        }
    for (ll i=0; i<=n; i++)
        f[0][i]=1;
    for (ll i=1; i<=pnum; i++){
        f[i][p[i]]=1;
        for (ll j=p[i]+1; j<=n; j++){
            for (ll k=p[i]; k<=j; k*=p[i])
                f[i][j]+=f[i-1][j-k];
    //      f[i][j]=max(f[i][j],f[i][j-1]);
        } 
        for (ll j=0; j<=n; j++)
            f[i][j]+=f[i-1][j];
    }
    printf("%lld\n",f[pnum][n]);    
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值