ZOJ 3662 Math Magic (2012 Changchun Regional; LCM,DP)

题目描述:给出K个数,使得这K个数的和为N,LCM为M,问有多少种.   裸DP啊……T T   设dp[i][j][k]表示取了i个数,和为j,LCM为k的时候的种数. 这样的话要开dp[100][1000][1000],需要优化. 首先第一维我们可以优化成滚动数组;其次, 因为LCM为M,那么中间状态的LCM肯定为M的约数,而且加入的数也肯定是M的约数,所以我们预处理出LCM的约数, 那么LCM和Ai只可能是那些约数,这样第三维又可以剪到40.最后开个dp[2][1000][40]就够了. 复杂度:O(100*1000*32*32)   (枚举第K个数*枚举当前和*枚举当前数的值*枚举LCM)  
#include 
 
   
    
  
#include 
  
    
      #include 
     
       #include 
      
        #include 
       
         #include 
        
          #include 
         
           #include 
          
            #include 
            #include 
            
              #include 
             
               #include 
              
                #define MID(x,y) ((x+y)>>1) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; int dp[2][1010][40]; int LCM[1010][1010]; bool tmp_ok[1000]; int N, M, K; const int MOD = 1000000007; vector 
               
                 divisor; int pos[1010]; int gcd(int a, int b){ return b ? gcd(b, a%b) : a; } int lcm(int a, int b){ return a / gcd(a,b) * b; } void get_divisor(int num){ mem(pos, -1); divisor.clear(); for (int i = 1; i <= num; i ++){ if (num % i == 0){ divisor.push_back(i); pos[i] = divisor.size() - 1; } } return ; } int main(){ mem(LCM, 0); for (int i = 1; i <= 1000; i ++) for (int j = 1; j <= 1000; j ++) LCM[i][j] = lcm(i, j); while(scanf("%d%d%d", &N, &M, &K) == 3){ get_divisor(M); mem(dp, 0); dp[0][0][0] = 1; for (int i = 1; i <= K; i ++){ mem(dp[i&1], 0); for (int j = 0; j <= N; j ++){ for (int p = 0; p < (int)divisor.size(); p ++){ //int tmp1 = divisor[p]; if (j + divisor[p] <= N){ for (int l = 0; l < (int)divisor.size(); l ++){ //int tmp2 = divisor[l]; if (dp[(i+1)&1][j][l] != 0){ int new_l = LCM[divisor[p]][divisor[l]]; if (new_l > M) break; new_l = pos[new_l]; dp[i&1][j+divisor[p]][new_l] += dp[(i+1)&1][j][l]; if (dp[i&1][j+divisor[p]][new_l] >= MOD) dp[i&1][j+divisor[p]][new_l] -= MOD; } } } } } } printf("%d\n", dp[K&1][N][pos[M]]); } return 0; } 
                
               
              
             
           
          
         
        
       
      
    
 
   
 

你可能感兴趣的:(Math)