zoukankan      html  css  js  c++  java
  • bzoj 1025: [SCOI2009]游戏

    这道题可以转换一下。

    试想每一个对应关系a-b为从a->b的一条边,

    那么图中一定存在n条边且每个点入度出度都为1,

    易证一定存在一个或几个环。

    实际上排数就是这几个环大小的最小公倍数。

    即求和为n的数列的最小公倍数种数。

    那么可以直接DP

     1 /*
     2 ID:WULALA
     3 PROB:bzoj1025 
     4 LANG:C++
     5 */
     6 #include <cstdio>
     7 #include <cstring>
     8 #include <algorithm>
     9 #include <cmath>
    10 #include <iostream>
    11 #include <ctime>
    12 #include <set>
    13 #define N 1008
    14 #define M
    15 #define mod
    16 #define mid(l,r) ((l+r) >> 1)
    17 #define INF 0x7ffffff
    18 using namespace std;
    19 
    20 int p[N],tot,n;
    21 long long f[2][N],sum;
    22 
    23 void find_prime()
    24 {
    25     bool vis[N];
    26     memset(vis,false,sizeof(vis));
    27     for (int i = 2;i <= n;i++)
    28         if (!vis[i])
    29         {
    30             p[++tot] = i;
    31             for (int j = i;j <= n;j+=i) vis[j] = true;
    32         }
    33 }
    34 
    35 void init()
    36 {
    37     scanf("%d",&n);
    38     find_prime();
    39     f[0][0] = 1;
    40 }
    41 
    42 void work()
    43 {
    44     for (int i = 1;i <= tot;i++)
    45     {
    46         for (int j = 0;j <= n;j++) f[i&1][j] = f[!(i&1)][j];
    47         for (int j = p[i];j <= n;j*=p[i])
    48             for (int k = 0;k <= n-j;k++) f[i&1][k+j] += f[!(i&1)][k];
    49     }
    50     for (int i = 0;i <= n;i++) sum += f[tot&1][i];
    51 }
    52 
    53 int main()
    54 {
    55     init();
    56     work();
    57     printf("%lld
    ",sum);
    58     return 0;
    59 }
    View Code
  • 相关阅读:
    第二次作业循环语句
    c语言01次作业分支,顺序结构
    PAT 1027. Colors in Mars
    PAT 1026 Table Tennis
    PAT 1035 Password
    PAT 1038. Recover the Smallest Number
    PAT 1028 List Sorting (25)
    PAT 1041 Be Unique (20)
    PAT 1025 PAT Ranking
    1037. Magic Coupon
  • 原文地址:https://www.cnblogs.com/wulala979/p/3529403.html
Copyright © 2011-2022 走看看