ZOJ Problem Set - 3662 Math Magic

 1 #include <iostream>
 2 #include <string.h>
 3 #include <string>
 4 #include <fstream>
 5 #include <algorithm>
 6 #include <stdio.h>
 7 #include <vector>
 8 #include <queue>
 9 #include <set>
10 #include <cmath>
11 using namespace std;
12 const double eps = 1e-8;
13 const double pi=acos(-1.0);
14 const int INF=0x7fffffff;
15 unsigned long long uINF = ~0LL;
16 #define MAXN 100007
17 #define mod 1000000007
18 typedef long long LL;
19 int gcd(int a,int b)
20 {
21     return b==0?a:gcd(b,a%b);
22 }
23 int N,M,K;
24 int LCM(int a,int b)
25 {
26     return a*b/gcd(a,b);
27 }
28 LL ans;
29 int dp[2][1001][101],lcm[1001][1001];
30 int pos[1001],num[1001];
31 
32 int main()
33 {
34 
35     for(int i=1;i<=1000;i++)
36     for(int j=1;j<=1000;j++)
37     lcm[i][j]=LCM(i,j);
38 
39     while(scanf("%d%d%d",&N,&M,&K)!=EOF)
40     {
41         ans=0;int cnt=0;
42         memset(pos,-1,sizeof(pos));
43         for(int i=1;i<=M;i++)
44         if(M%i==0)
45         {
46             num[cnt]=i;
47             pos[i]=cnt++;
48         }
49         memset(dp[0],-1,sizeof(dp[0]));
50         dp[0][0][0]=1;
51         for(int i=1;i<=K;i++)
52         {
53             memset(dp[i&1],-1,sizeof(dp[i&1]));
54             for(int j=i-1;j<=N;j++)
55             {
56                 for(int k=0;k<cnt;k++)
57                 {
58                     if(dp[(i+1)&1][j][k]==-1)continue;
59                     for(int r=0;r<cnt&&j+num[r]<=N;r++)
60                     {
61                         int l=j+num[r];
62                         int s=lcm[num[r]][num[k]];
63                         if(s<=M&&pos[s]!=-1)
64                         {
65                             s=pos[s];
66                             if(dp[i&1][l][s]==-1)dp[i&1][l][s]=0;
67                             dp[i&1][l][s]+=dp[(i+1)&1][j][k];
68                             if(dp[i&1][l][s]>=mod)dp[i&1][l][s]-=mod;
69                         }
70                     }
71                 }
72             }
73         }
74         printf("%d\n",dp[K&1][N][pos[M]]==-1?0:dp[K&1][N][pos[M]]);
75     }
76     return 0;
77 }

dp,dp[i][j][k]表示取了i个数,和为j,LCM为状态k的时候的种数

posted @ 2013-08-01 16:37  TO_Asia  阅读(177)  评论(0编辑  收藏  举报