标签: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