题意:
链接:https://www.nowcoder.com/acm/contest/107/G
来源:牛客网
初始的时候小国和小杰各有1个。经过了很久的修炼,汀老师学会了两种魔法,他每次可以动用自己的智慧来使用魔法。
第一个魔法:(小杰变小国)可以将自己的智慧复制和当前小杰一样数量的小国出来;
第二个魔法:(小国大爆发)可以将当前的小杰变成和小国的数量一样,然后小国的数量加倍!
题解:将两个参数化为一维,于是有一个递推方程a[j + i] = min(a[j + i], a[i] + j / i);
疑问:1e6的循环能过?
ac核心代码。
memset(a, 0x3f, sizeof(a)); a[1] = 0; for (int i = 1; i <= 1000000; ++i) for (int j = i; j + i <= 1000000; j += i) a[j + i] = min(a[j + i], a[i] + j / i);
附:数论模板orz
#include <iostream> #include <vector> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> using namespace std; class NumberTheory { public: // 预打标后的数的最小因子 std::vector<unsigned int> MinFactor; // 预打表中搜索到的素数集 std::vector<unsigned int> Prime; // 预打表欧拉函数 std::vector<unsigned int> Phi; // 预打表最大数 unsigned int MaxNumber; // 用于递归传递参数 没有实质作用 std::vector<long long int> temp; // 不打表构造函数 NumberTheory() { MaxNumber = 0; } // 预打表到MaxNumber构造函数 explicit NumberTheory(unsigned int MaxNumber) { this->MaxNumber = MaxNumber; MaxNumber = std::max(MaxNumber + 1, (unsigned int) 2); Phi.resize(MaxNumber); MinFactor.resize(MaxNumber); MinFactor[1] = 1; Phi[1] = 1; for (unsigned int i = 2; i < MaxNumber; i++) { if (Phi[i] == 0) { Prime.push_back(i); Phi[i] = i - 1; MinFactor[i] = i; } for (unsigned int j = 0; j < Prime.size() && Prime[j] * i < MaxNumber; j++) { if (i % Prime[j] == 0) { MinFactor[i * Prime[j]] = Prime[j]; Phi[i * Prime[j]] = Phi[i] * Prime[j]; break; } MinFactor[i * Prime[j]] = Prime[j]; Phi[i * Prime[j]] = Phi[i] * (Prime[j] - 1); } } } long long int abs(int x) { return x > 0 ? x : -x; } // 快速幂 long long fastpower(long long a, long long n) { long long res = 1; while (n > 0) { if (n & 1)res = res * a; a = a * a; n >>= 1; } return res; } // 判断是否是素数 bool IsPrime(long long int n) { if (n <= MaxNumber) // 在表中O(1)查表 return MinFactor[n] == n; // 不在表中用Miller_Rabin return Miller_Rabin(n); } // 最大公约数 long long int gcd(long long int a, long long int b) { return b ? gcd(b, a % b) : a; } // 多个数最大公约数 long long int gcd(std::vector<int> v) { if (v.size() < 2) return -1; long long int res = v[0]; for (int i = 1; i < v.size(); i++) { res = gcd(res, v[i]); } return res; } // 最小公倍数 long long int lcm(long long int a, long long int b) { return a * b / gcd(a, b); } // 带模快速乘法 long long int modular_multi(long long int x, long long int y, long long int mo) { long long int t; x %= mo; for (t = 0; y; x = (x << 1) % mo, y >>= 1) if (y & 1) t = (t + x) % mo; return t; } /*long long int modular_exp(char *N, long long int t, long long int mo) { //unsure!!! return modular_exp(t,PhiMa(N,mo),mo); }*/ // 带模快速幂 long long int modular_exp(long long int num, long long int t, long long int mo) { long long int ret = 1, temp = num % mo; for (; t; t >>= 1, temp = modular_multi(temp, temp, mo)) if (t & 1) ret = modular_multi(ret, temp, mo); return ret; } // 费马小定理整理指数 long long int PhiMa(char *N, int mod) { long long ans = 0; for (int i = 0; N[i] != '