POI2004MAK
dp #贪心 #构造 #POI #Year2004
order
等于所有环的长度的 \(lcm\)
\(dp_{i,j}\) 表示前 \(i\) 个质数组成和为 \(j\) 的最大 \(lcm\) 每个数一定是 \(p^k\),其它方案在贪心上都是不优的
在 \(dp\) 的时候记录方案,尽可能优先选择较大的
然后构造方案,将较小的环贪心的往前放
// Author: xiaruize
#ifndef ONLINE_JUDGE
bool start_of_memory_use;
#endif
#include <bits/stdc++.h>
using namespace std;
#ifndef ONLINE_JUDGE
clock_t start_clock = clock();
#endif
#define double long double
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b)
{
if (a > b)
return a;
return b;
}
int min(int a, int b)
{
if (a < b)
return a;
return b;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 1e4 + 10;
double dp[205][N];
int pre[205][N];
bool ntpr[N];
vector<int> pr;
int n;
void init()
{
rep(i, 2, 1e4)
{
if (!ntpr[i])
pr.push_back(i);
if (pr.size() > 200)
break;
for (auto v : pr)
{
if (v * i > 1e4)
break;
ntpr[i * v] = true;
if (i % v == 0)
break;
}
}
// cerr << pr.size() << endl;
rep(i, 0, 1e4) dp[0][i] = 1;
rep(i, 0, pr.size() - 1)
{
int x = pr[i];
// cerr << x << endl;
// double cnt = log2(x);
memcpy(dp[i + 1], dp[i], sizeof(dp[i]));
// cerr << cnt << endl;
rep(j, 0, 1e4)
{
for (int cur = x, p = 1; cur + j <= 1e4; cur *= x, p++)
{
if (dp[i + 1][j + cur] <= dp[i][j] * cur)
{
dp[i + 1][j + cur] = dp[i][j] * cur;
pre[i + 1][j + cur] = cur;
}
}
}
}
}
void solve()
{
cin >> n;
int cur = n;
vector<int> res;
per(i, pr.size(), 1)
{
int x = pre[i][cur];
// cerr << i << ' ' << cur << endl;
if (x)
res.push_back(x);
cur -= x;
}
while (cur--)
res.push_back(1);
sort(ALL(res));
// for (auto v : res)
// cerr << v << ' ';
int sum = 1;
for (auto v : res)
{
// cerr << v << ' ';
rep(i, sum + 1, sum + v - 1) cout << i << ' ';
cout << sum << ' ';
sum += v;
}
// cerr << endl;
cout << endl;
}
#ifndef ONLINE_JUDGE
bool end_of_memory_use;
#endif
signed main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
init();
int testcase = 1;
cin >> testcase;
while (testcase--)
solve();
#ifndef ONLINE_JUDGE
cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl;
cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl;
#endif
return 0;
}