一开始用搜索直接超时,看题解会的
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 }
时间: 2024-10-10 09:35:17