您的位置:首页 > 其它

BZOJ1025 [SCOI2009]游戏

2014-10-18 15:24 615 查看
题意:对于一些长度为n的排列,将其作为一个置换,那么可能有一个自置换的次数使其回到1,2,3,...,n的情况。求对于所有能够回到1,2,3..,n的排列,不同的次数共有多少种。

思路:我们将置换划分成循环节的形式,那么我们发现最终可能的置换一定是这种形式:

(2,1)(3)(5,6,4)(7)

1,2->2,1

3->3

4,5,6->5,6,4

7->7

并且,若一段的长度为L,那么在第一行下面就是每L行一个循环。最后一行就是我们想要的正序排列。

那么总的行数就是1+LCM(L1,L2,L3,L4,...Lk).

其中k表示划分为k段,并且有L1+L2+L3+...+Lk=n.

于是问题转化为k个正整数,和为n,求他们的最小公倍数的数目。

事实上,k是不确定的,并不容易处理。于是我们转而考虑某个答案ans=p1^a1*p2^a2*..*pm^am是否是n的一个可行答案。

我们有以下结论:若p1^a1+p2^a2+...+pm^am<=n,则ans=p1^a1*p2^a2*..*pm^am是n的一个可行答案。

这个现在我只能给出一种比较正确的证明。

利用反证法证明:不妨设n的某个可行答案ans=p1^a1*p2^a2*p3^a3*...*pm^am,且p1^a1+p2^a2+p3^a3+...+pm^am>n.

由于p1^a1在LCM中,那么必然有某个L是p1^a1的倍数。但是有一些L非常牛,可能是多个pi^ai的倍数。

不妨举个小例子:

设L1是p1^a1的倍数,L3是p2^a2*p3^a3*p4^a4的倍数(L2呢?打酱油去啦~~),L4是p5^a5的倍数,L5是p6^a6*p7^a7的倍数,剩下的L都打酱油去了。

然后显然有L1+L3+L4+L5=b1*p1^a1+b2*p2^a2*p3^a3*p4^a4+b3*p5^a5+b4*p6^a6*p7^a7<=n(因为有一些L打酱油去了)

这里有b1,b2,b3,b4为正整数。

而又有p1^a1+p2^a2+p3^a3+...+p7^a7>n,那么由于都是大于1的数,我们可以认为在每一段内都有乘积比和要大,再乘以一个倍数,必然也比和要大,那么就有:

L1+L3+L4+L5=b1*p1^a1+b2*p2^a2*p3^a3*p4^a4+b3*p5^a5+b4*p6^a6*p7^a7>n

产生矛盾!

那么我们就证明了上述结论。

那么现在问题就转化为求有多少种(a1,a2,a3,...am),满足p1^a1+p2^a2+p3^a3+...+pm^am<=n

利用分组背包就可以通过了。

注意边界条件。

代码:

/**
* Author: wyfcyx
* Problem: BZOJ1025
* Keywords: Math, Dynamic Programming
* Time Complexity: O(N*N/logN*logN)=O(N^2)
* Created Time: 14-10-18
**/

#include <cstdio>
#include <cstring>
#include <cctype>
#include <iostream>
#include <algorithm>
using namespace std;

const int N = 1000;
int p
, id;
bool notp[N + 1];
void pre() {
int i, j;
for(i = 2; i <= N; ++i) {
if (!notp[i])
p[++id] = i;
for(j = 1; j <= id && i * p[j] <= N; ++j) {
notp[i * p[j]] = 1;
if (i % p[j] == 0)
break;
}
}
}

unsigned long long f[200][1001];

int main() {
int n;
scanf("%d", &n);

pre();

register int i, j, k;
for(i = 0; i <= id; ++i)
f[i][0] = 1;
for(j = 1; j <= n; ++j)
f[0][j] = 1;
for(i = 1; i <= id; ++i) {
for(j = 1; j <= n; ++j) {
f[i][j] = f[i - 1][j];
for(k = p[i]; k <= j; k *= p[i])
f[i][j] += f[i - 1][j - k];
}
}
printf("%llu", f[id]
);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: