hdoj 4028(离散DP)
2014-08-25 16:35
148 查看
刚开始的时候一直以为是数论,最后搞不定。看了大牛的博客,才知道是dp,离散DP。高大上~
知道是dp后,越来越觉得很明显的dp嘛,一开始就是脑残啊。
显然是存在明显的递推关系,但是由于数据的范围比较大,直接开数组是不行的
所幸,最小公倍数的个数不是很多。所以采用了离散化。就有了离散DP!
别的不说了,具体的说明在代码里。
代码如下:
知道是dp后,越来越觉得很明显的dp嘛,一开始就是脑残啊。
显然是存在明显的递推关系,但是由于数据的范围比较大,直接开数组是不行的
所幸,最小公倍数的个数不是很多。所以采用了离散化。就有了离散DP!
别的不说了,具体的说明在代码里。
代码如下:
/*dp[i]=dp[i-1]//继承 **dp[i][j]=d[i][j]+dp[i-1][k] ,j=lcm(i,k) j是i和k的最小公倍数 **dp[i][j]的含义是前i根针的组合中最小公倍数为j的数量, */ //由于数的范围比较大,但是个数比较少,所以采用离散dp。 //即 用map<__int64,__int64>表示最小公倍数为it->first,有it->second个。 //#pragma warning(disable : 4786) #include <iostream> #include<algorithm> #include<cstdio> #include<map> #include<string> using namespace std; int n,T,casei; __int64 M,ans; map<__int64,__int64> dp[45]; __int64 gcd(__int64 a,__int64 b) { if(a==0) return b; return gcd(b%a,a); } __int64 lcm(__int64 a,__int64 b) { return a/gcd(a,b)*b; } void init() { int i,j; dp[0][1]=1; for(i=1;i<=40;i++) { dp[i]=dp[i-1]; for(map<__int64,__int64>::iterator it=dp[i-1].begin();it!=dp[i-1].end();it++) { dp[i][lcm(it->first,i)]+=it->second; } } } int main() { int i,j; init(); scanf("%d",&T); while(T--) { casei++; ans=0; scanf("%d%I64d",&n,&M); for(map<__int64,__int64>::iterator it=dp .begin();it!=dp .end();it++) { if(it->first>=M) ans+=it->second; } if(M==1) ans--; printf("Case #%d: %I64d\n",casei,ans); } return 0; }
相关文章推荐
- hdoj4028(离散DP)
- hdu 4028 2011上海赛区网络赛H dp+map离散
- hdoj1208_Pascal's Travels(dp)
- HDOJ1876 DP问题
- HDOJ-1011(树形DP)
- HDOJ 5155 Harry And Magic Box DP
- 【HDOJ6148】Valley Numer(数位DP)
- hdoj 3555 Bomb/ hdoj 3652 B-number 数位DP 初解禁!!
- hdoj 4939 Stupid Tower Defense 【DP】
- hdoj 4405 Aeroplane chess(概率dp)
- HDOJ1069 Monkey and Banana【dp】
- HDOJ 题目1561 The more, The Better(树状dp)
- HDOJ 5115 Dire Wolf 区间DP
- DP入门, 0-1背包问题(HDOJ 2602类似)
- hdoj MAX Average Problem 2993 (斜率优化DP)
- hdoj 5045 期望dp
- HDOJ1160 FatMouse's Speed[dp](最长上升子序列)
- HDOJ 5125 magic balls DP
- 【DP】 HDOJ 3357 Stock Chase
- HDOJ 1565 方格取数(1)(状态压缩dp)