HDU 4028 The time of a day [离散化DP]

  虽然数很大,但是这40个数的公倍数一共才4万多个。这里用到STL会方便很多,map[i]里存放了从1~i能组成的公倍数有哪些以及每个数有多少种组成方法。

  预处理一遍打个表然后每次O(n)的遍历一遍,否则会超时。

  

#include <string.h>
#include <stdio.h>
#include <map>
typedef __int64 LL;
int n,cas;
LL m,ans;
std::map<LL,LL> mp[41];
std::map<LL,LL>::iterator it;
LL gcd(LL a,LL b){
    return b==0?a:gcd(b,a%b);
}
//初始化,否则会超时
void init(){
    for(int i=1;i<=40;i++){
        for(mp[i]=mp[i-1],it=mp[i-1].begin();it!=mp[i-1].end();it++){
            LL num=it->first;
            LL x=i*num/gcd(i,num);
            mp[i][x]+=it->second;
        }
        mp[i][i]++;
    }
}
int main(){
    //freopen("test.in","r",stdin);
    scanf("%d",&cas);
    init();
    for(int ca=1;ca<=cas;ca++){
        scanf("%d%I64d",&n,&m);
        ans=0;
        for(it=mp[n].begin();it!=mp[n].end();it++){
            if(it->first>=m)ans+=it->second;
        }
        printf("Case #%d: %I64d\n",ca,ans);
    }

}
posted @ 2012-08-27 23:41  Burn_E  阅读(157)  评论(0编辑  收藏  举报