您的位置:首页 > 其它

HDU 4028 The time of a day(DP)

2015-09-04 22:20 330 查看
题目链接:acm.hdu.edu.cn/showproblem.php?pid=4028

题意:题目转化后就是在1~N中任选数字组成LCM,问有多少种组法使得LCM >= M

思路:考虑dp[i][j]为选至第i个数lcm为j的方案数,考虑lcm值很大会爆内存,但是可组成的lcm的个数不算特别多,故考虑用map进行映射,每个map保存lcm值和方案数两个值,根据lcm的值进行转移

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#include <climits>
#include <functional>
#include <deque>
#include <ctime>

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#pragma comment(linker, "/STACK:102400000,102400000")

using namespace std;

typedef long long ll;

const int maxn = 100010;

map <ll, ll> dp[50];

ll gcd(ll x, ll y)
{
return y == 0 ? x : gcd(y, x % y);
}

ll lcm(ll x, ll y)
{
return x / gcd(x, y) * y;
}

void init()
{
dp[1][1] = 1;
for (int i = 2; i <= 40; i++)
{
dp[i] = dp[i - 1]; //不选第i个数

dp[i][i]++; //只选第i个数
for (map <ll, ll> ::iterator it = dp[i - 1].begin(); it != dp[i - 1].end(); it++)
{
ll val = it->first;
dp[i][lcm(val, i)] += it->second;
}
}
}

int main()
{
init();
int t;
cin >> t;
for (int ca = 1; ca <= t; ca++)
{
printf("Case #%d: ", ca);
ll n, m;
cin >> n >> m;

ll ans = 0;
for (map <ll, ll> ::iterator it = dp
.begin(); it != dp
.end(); it++)
if (it->first >= m)
ans += it->second;
cout << ans << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: