zoukankan      html  css  js  c++  java
  • hdu 4427 Math Magic

    dp[i][j][k]为i个数,和为j,最小公倍数为k,满足的个数。

    dp[i+1][j+v][ lcm[k][v] ]+=dp[i][j][k]

    4层for循环,枚举i,j,k,v,朴素肯定超时,加上优化。

    首先可以预处理1000以内每两个数的最小公倍数。

    其次,枚举v的时候,只需要枚举m的因子就够了,因为他们要构成最小公倍数为m,必须每个数都是m的因子。这样的话k和j的枚举都降到很小了。

    由于100*1000*1000的int开不下,观察转移方程,i+1只和i有关,所以可以采用滚动数组。

    不加上面的优化,很容易超时。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define MOD 1000000007
    int lcm[1005][1005];
    int dp[2][1005][1005];
    int v[105];
    inline int gcd(int a,int b)
    {
        return a%b==0?b:gcd(b,a%b);
    }
    int main()
    {
        int n,m,k;
        for(int i=1;i<=1000;i++)
            for(int j=1;j<=1000;j++)
                if(!lcm[i][j]) lcm[j][i]=lcm[i][j]=i/gcd(i,j)*j;
        while(scanf("%d%d%d",&n,&m,&k)!=EOF)
        {
            int top=0,tmp=sqrt(m*1.0);
            for(int i=1;i<=tmp;i++)
            {
                if(m%i==0) {
                    v[top++]=i;
                    if(i!=m/i)
                        v[top++]=m/i;
                }
            }
            sort(v,v+top);
            for(int i=0;i<=n;i++)
            memset(dp[0][i],0,sizeof(dp[0][i])),
            memset(dp[1][i],0,sizeof(dp[1][i]));
            for(int i=0;i<top;i++) dp[0][v[i]][v[i]]=1;
            int t=0;
            for(int i=1;i<k;i++)   //i个数
            {
                for(int ii=i;ii<=n;ii++)
                    for(int jj=0;jj<top;jj++)
                        dp[t^1][ii][v[jj]]=0;
                for(int j=i;j<n;j++)   //和为j
                    for(int w=0;w<top;w++) //最小公倍数为v[w]
                    {
                        if(dp[t][j][v[w]])
                        for(int s=0;j+v[s]<=n&&s<top;s++)  //最后一个数为v[s]
                        {
                            dp[t^1][j+v[s]][ tmp=lcm[v[w]][v[s]] ]+=dp[t][j][v[w]];
                            dp[t^1][j+v[s]][tmp]%=MOD;
                        }
                    }
                t^=1;
            }
            printf("%d
    ",dp[t][n][m]);
        }
        return 0;
    }
    


  • 相关阅读:
    Codeforces 877 C. Slava and tanks
    Codeforces 877 D. Olya and Energy Drinks
    2017 10.25 NOIP模拟赛
    2017 国庆湖南 Day1
    UVA 12113 Overlapping Squares
    学大伟业 国庆Day2
    51nod 1629 B君的圆锥
    51nod 1381 硬币游戏
    [JSOI2010]满汉全席
    学大伟业 2017 国庆 Day1
  • 原文地址:https://www.cnblogs.com/bbsno1/p/3278121.html
Copyright © 2011-2022 走看看