hdu 4028 2011上海赛区网络赛H dp+map离散

一开始用搜索直接超时,看题解会的

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<map>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<vector>
 7 #include<queue>
 8 #include<algorithm>
 9 #include<set>
10 #define inf 110000
11 #define M 10005
12 #define N 10005
13 #define Min(a,b) ((a)<(b)?(a):(b))
14 #define Max(a,b) ((a)>(b)?(a):(b))
15 #define pb(a) push_back(a)
16 #define mem(a,b) memset(a,b,sizeof(a))
17 #define eps 1e-9
18 #define zero(a) fabs(a)<eps
19 #define LL long long
20 #define MOD 1000000007
21 using namespace std;
22 map<LL,LL>dp[45];
23 map<LL,LL>::iterator it;
24 LL gcd(LL a,LL b){
25     return b==0?a:gcd(b,a%b);
26 }
27 LL lcm(LL a,LL b){
28     return a/gcd(a,b)*b;
29 }
30 void DP(){
31     dp[1][1]=1;
32     for(int i=2;i<=40;i++){
33         dp[i]=dp[i-1];   //不取第i个数的所有情况,先复制过来
34         dp[i][i]++;      //只取第i个数,不能落下
35         for(it=dp[i-1].begin();it!=dp[i-1].end();it++)
36             dp[i][lcm(i,it->first)]+=it->second;   //然后考虑在前i-1个数的基础上加入第i个数
37     }
38 }
39 LL n,m;
40 int main(){
41     DP();
42     int t,cas=0;
43     scanf("%d",&t);
44     while(t--){
45         scanf("%I64d%I64d",&n,&m);
46         LL ans=0;
47         //遍历一遍
48         for(it=dp[n].begin();it!=dp[n].end();it++)
49             if(it->first>=m)
50                 ans+=it->second;
51         printf("Case #%d: %I64d\n",++cas,ans);
52     }
53     return  0;
54 }

 

posted @ 2015-07-30 16:40  miao_a_miao  阅读(162)  评论(0编辑  收藏  举报