BZOJ1025 游戏

题解:

所谓对应关系,其实就是一种置换(想成一种环)。对于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;
}
时间: 2024-12-18 03:07:18

BZOJ1025 游戏的相关文章

[BZOJ1025] [SCOI2009]游戏 解题报告

Description windy学会了一种游戏.对于1到N这N个数字,都有唯一且不同的1到N的数字与之对应.最开始windy把数字按顺序1,2,3,……,N写一排在纸上.然后再在这一排下面写上它们对应的数字.然后又在新的一排下面写上它们对应的数字.如此反复,直到序列再次变为1,2,3,……,N. 如: 1 2 3 4 5 6 对应的关系为 1->2 2->3 3->1 4->5 5->4 6->6 windy的操作如下 1 2 3 4 5 6 2 3 1 5 4 6

BZOJ1025: [SCOI2009]游戏

1025: [SCOI2009]游戏 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2029  Solved: 1315[Submit][Status][Discuss] Description windy学会了一种游戏.对于1到N这N个数字,都有唯一且不同的1到N的数字与之对应.最开始windy把数字按顺序1,2,3,……,N写一排在纸上.然后再在这一排下面写上它们对应的数字.然后又在新的一排下面写上它们对应的数字.如此反复,直到序列再次变为1,

【bzoj1025】【SCOI2009】【游戏】【dp】

Description windy学会了一种游戏.对于1到N这N个数字,都有唯一且不同的1到N的数字与之相应.最開始windy把数字按顺序1,2.3.--,N写一排在纸上. 然后再在这一排以下写上它们相应的数字.然后又在新的一排以下写上它们相应的数字.如此重复,直到序列再次变为1.2,3,--.N. 如: 1 2 3 4 5 6 相应的关系为 1->2 2->3 3->1 4->5 5->4 6->6 windy的操作例如以下 1 2 3 4 5 6 2 3 1 5 4

[bzoj1025][SCOI2009]游戏 (分组背包)

Description windy学会了一种游戏.对于1到N这N个数字,都有唯一 且不同的1到N的数字与之对应.最开始windy把数字按顺序1,2,3,……,N写一排在纸上.然后再在这一排下面写上它们对应的数字.然后又在新的一 排下面写上它们对应的数字.如此反复,直到序列再次变为1,2,3,……,N. 如: 1 2 3 4 5 6 对应的关系为 1->2 2->3 3->1 4->5 5->4 6->6 windy的操作如下 1 2 3 4 5 6 2 3 1 5 4

bzoj1025: [SCOI2009]游戏(DP)

题目大意:将长度为n的排列作为1,2,3,...,n的置换,有可能置换x次之后,序列又回到了1,2,3,...,n,求所有可能的x的个数. 看见这种一脸懵逼的题第一要务当然是简化题意...我们可以发现,序列回到原状的次数就是每个循环的规模(即在循环中的数字个数)的lcm,而且因为有n个数,显然所有循环的规模之和就是n,那么问题就被简化成了a1+a2+a3+...+ak=n,求lcm(a1,a2,a3,...,an)的个数. 现在题意已经清楚多了,那咋写呢QAQ 我们把一个数分解质因数,p为质数,

bzoj1025 [SCOI2009]游戏——因数DP

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1025 这篇博客写得真好呢:https://www.cnblogs.com/phile/p/4473192.html 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,pri[1005],cnt; long long f[1005][1005]

20170913自制猜数字游戏

/* 猜数字:系统随机生成一个四位数,请根据下列判断猜出来 A:数值正确,位置正确 B:数值正确,位置不正确 C:数值不正确 */ #include<stdio.h> #include<time.h> #include<stdlib.h> #pragma warning (disable:4996) #define pUCharHead unsigned char * //以数组形式返回n个无重复的随机数,范围可指定[min,max] pUCharHead GenNoR

洛谷P1199 三国游戏

题目描述 小涵很喜欢电脑游戏,这些天他正在玩一个叫做<三国>的游戏. 在游戏中,小涵和计算机各执一方,组建各自的军队进行对战.游戏中共有 N 位武将(N为偶数且不小于 4),任意两个武将之间有一个"默契值",表示若此两位武将作为一对组合作战时,该组合的威力有多大.游戏开始前,所有武将都是自由的(称为自由武将,一旦某个自由武将被选中作为某方军队的一员,那么他就不再是自由武将了),换句话说,所谓的自由武将不属于任何一方. 游戏开始,小涵和计算机要从自由武将中挑选武将组成自己的军

游戏开发 系统app开发游戏定制开发找谁

梦幻珍珠港理财拆分游戏系统软件开发怎么做?找[江生:185-2911-8412 微电]. 梦幻珍珠港拆分游戏平台开发.梦幻珍珠港理财全网模式开发.梦幻珍珠港收益模式介绍开发. 梦幻珍珠港拆分游戏系统源码搭建平台!!我们是软件开发,玩家勿扰!非平台客服,玩家勿扰!] 游戏规则: 一.开发新会员要从您的库房扣除3 03颗珍珠,体系扣除5颗珍珠,新会员有298颗珍珠. 二.推荐老友,推荐人能够得到第一代会员的2%,第二代会员的1%,第三代会员的0.5%,一代的收益就是5.96颗珍珠奖赏(可转换为等量可