bzoj 1025 [SCOI2009]游戏 dp

Posted copperoxide

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1025 [SCOI2009]游戏 dp相关的知识,希望对你有一定的参考价值。

题面

题目传送门

解法

显然,可以回到初始状态就意味着一定由若干个环组成
假设环的长度为(l_i)
那么,我们可以得到(sum l_i=n)
不考虑自环的情况,那么(sum l_i≤n)
(n)以内的质因数全部筛出,强制每一次只取某一个质数的次幂,那么就可以解决重复计数的问题
时间复杂度:(O(n^2))

代码

#include <bits/stdc++.h>
#define int long long
#define N 1010
using namespace std;
template <typename node> void chkmax(node &x, node y) {x = max(x, y);}
template <typename node> void chkmin(node &x, node y) {x = min(x, y);}
template <typename node> void read(node &x) {
    x = 0; int f = 1; char c = getchar();
    while (!isdigit(c)) {if (c == ‘-‘) f = -1; c = getchar();}
    while (isdigit(c)) x = x * 10 + c - ‘0‘, c = getchar(); x *= f;
}
int len, a[N], f[N][N];
bool prime(int x) {
    for (int i = 2; i * i <= x; i++)
        if (x % i == 0) return false;
    return true;
}
void sieve(int n) {
    len = 0;
    for (int i = 2; i <= n; i++)
        if (prime(i)) a[++len] = i;
}
main() {
    int n; read(n);
    sieve(n); f[0][0] = 1;
    for (int i = 1; i <= len; i++)
        for (int j = 0; j <= n; j++) {
            f[i][j] += f[i - 1][j];
            for (int k = a[i]; j + k <= n; k = k * a[i])
                f[i][j + k] += f[i - 1][j];
        }
    int ans = 0;
    for (int i = 0; i <= n; i++) ans += f[len][i];
    cout << ans << "
";
    return 0;
}





以上是关于bzoj 1025 [SCOI2009]游戏 dp的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1025 [SCOI2009]游戏——因数DP

bzoj1025SCOI2009游戏dp

bzoj 1025 [SCOI2009]游戏 dp

BZOJ.1025.[SCOI2009]游戏(背包DP)

BZOJ1025 [SCOI2009]游戏 置换群 + 背包dp

bzoj1025: [SCOI2009]游戏(DP)