码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ1025 游戏

时间:2016-08-11 06:20:40      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:

题解:

所谓对应关系,其实就是一种置换(想成一种环)。对于n个数,一共有m个置换,每个置换的大小为a1,a2,.....am

转化为求a1+a2+.....am=n的最小公倍数的种类(不同的最小公倍数有多少个)

置换的大小可以为1,转化为a1+a2+.....am<=n的最小公倍数的种类

对于每个ai,可以用k个素数的乘积表示

转化为有p个不同的素数,每个素数的幂的最大值的乘积的不同数,保证全部素数的最大幂和<=n

然后dp来做就行了

参考博客

http://www.cnblogs.com/iwtwiioi/p/4104385.html

代码:

 第一种 dp[i][j]表示前i个素数和为j的所有可能,使用滚动数组节省空间

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define se second
#define fs first
#define ll long long
#define CLR(x) memset(x,0,sizeof x)
#define MC(x,y) memcpy(x,y,sizeof(x))  
#define SZ(x) ((int)(x).size())
#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 
#define INF 2097152
typedef pair<int,int> P;
const double eps=1e-9;
const int maxn=1050;
const int mod=1e9+7;
 
ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
//-----------------------------------------------------------------------------
 
int p[maxn],vis[maxn],n,cnt;
ll  dp[2][maxn];
 
void get_prime()
{
    for(int i=2;i<=n;i++)
    {
        if(!vis[i]) p[++cnt]=i;
        for(int j=1;j<=cnt&&p[j]*i<=n;j++)
        {
            vis[p[j]*i]=1;
            if(!(i%p[j])) break;
        }
    }
}
 
int main()
{
    n=read();cnt=0;
    get_prime();
    int now=1,last=0;
    dp[last][0]=1;
    for(int i=1;i<=cnt;i++)
    {
        for(int j=0;j<=n;j++)
        {
            dp[now][j]=dp[last][j];
            for(int k=p[i];j-k>=0;k*=p[i]) dp[now][j]+=dp[last][j-k];
        }
        //for(int j=0;j<=n;j++) dp[last][j]=0;
        now^=1;
        last^=1;
    }
    ll ans=0;
    for(int i=0;i<=n;i++) ans+=dp[last][i];
    printf("%lld\n",ans);
    return 0;
}

第二种 dp[i][j]表示前i个素数和不超过j的所有可能情况

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define se second
#define fs first
#define ll long long
#define CLR(x) memset(x,0,sizeof x)
#define MC(x,y) memcpy(x,y,sizeof(x))  
#define SZ(x) ((int)(x).size())
#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 
#define INF 2097152
typedef pair<int,int> P;
const double eps=1e-9;
const int maxn=1050;
const int mod=1e9+7;

ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
//-----------------------------------------------------------------------------

int p[maxn],vis[maxn],n,cnt;
ll  dp[170][maxn];

void get_prime()
{
    for(int i=2;i<=n;i++)
    {
        if(!vis[i]) p[++cnt]=i;
        for(int j=1;j<=cnt&&p[j]*i<=n;j++)
        {
            vis[p[j]*i]=1;
            if(!(i%p[j])) break;
        }
    }
}

int main()
{
    n=read();cnt=0;
    get_prime();
    for(int i=0;i<=cnt;i++) dp[i][0]=1;
    for(int j=0;j<=n;j++) dp[0][j]=1;
    for(int i=1;i<=cnt;i++)
    {
        for(int j=0;j<=n;j++)
        {
            dp[i][j]=dp[i-1][j];
            for(int k=p[i];k<=j;k*=p[i]) dp[i][j]+=dp[i-1][j-k];
        }
    }
    printf("%lld\n",dp[cnt][n]);
    return 0;
}

 

BZOJ1025 游戏

标签:

原文地址:http://www.cnblogs.com/byene/p/5759411.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!