标签:des style blog io color ar os for sp
Description
Input
Output
Sample Input
3 5 5 10 1 10 128
Sample Output
Case #1: 22 Case #2: 1023 Case #3: 586
题意:给出1-n的数字,问有多少的子集的lcm是大于等于m的
思路:m很大,子集也有2^40,但是发现最小公倍数的范围只有4万多个,所以可以用dp[i][j]表示前i个数最小公倍数是j的方案数,离散处理最小公倍数的结果节省空间
#include <iostream> #include <cstdio> #include <cstring> #include <map> #include <algorithm> //typedef long long ll; typedef __int64 ll; using namespace std; map<ll, ll> dp[50]; ll gcd(ll a, ll b) { return (b == 0) ? a : gcd(b, a%b); } ll lcm(ll a, ll b) { return a / gcd(a, b) * b; } void init() { dp[1][1] = 1; map<ll, ll>::iterator it; for (int i = 2; i <= 40; i++) { dp[i] = dp[i-1]; dp[i][i]++; for (it = dp[i-1].begin(); it != dp[i-1].end(); it++) dp[i][lcm(i, it->first)] += it->second; } } int main() { init(); int t, cas = 1; scanf("%d", &t); int n; ll m; while (t--) { scanf("%d%I64d", &n, &m); ll ans = 0; map<ll, ll>::iterator it; for (it = dp[n].begin(); it != dp[n].end(); it++) if (it->first >= m) ans += it->second; printf("Case #%d: %I64d\n", cas++, ans); } return 0; }
HDU - 4028 The time of a day(离散+DP)
标签:des style blog io color ar os for sp
原文地址:http://blog.csdn.net/u011345136/article/details/40836529