//https://www.luogu.com.cn/problem/P7690
#include<bits/stdc++.h>
#include<unordered_map>
#include<array>
#define ll long long
#define ull unsigned long long
#define all(a) a.begin(),a.end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const int N = 2e5 + 5;
ll n, m, f[25][25][2], vis[25];
/*
f[i][j][k] : 总共i个数, 排列后第一数是第j大, 且第一位数的状态为k
k = 0, 第一个数小于第二个数
k = 1, 第一个数大于第二个数
n个数字符合要求的排列总数为f[n][1 ~ n][0 ~ 1]的和
*/
void init()
{
fill(vis, vis + n + 1, 0);
memset(f, 0, sizeof f);
f[1][1][0] = f[1][1][1] = 1;
for (int i = 2; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
for (int k = 1; k < i; k++)//加入一个数后j作为第一个数字的排列方式为i - 1个数字时比大于等于j的数字都加一, 其余不变
{
if (k < j)
f[i][j][1] += f[i - 1][k][0];//第一个数为高位, 第二个数字选择比第一个数字小的
else
f[i][j][0] += f[i - 1][k][1];//第一个数为低位, 第二个数字选择比第一个数字大的
}
}
}
}
void solve()//试填法, 从左到右依次确定每一位的数字
{
cin >> n >> m;
init();
vector<int> ans;
int last, k;
for (int i = 1; i <= n; i++)//无法确定第一个数字是高危还是低位, 需要讨论
{
if (f[n][i][1] >= m)//因为按字典序排列, 当前位相同, 则当前位是高位使得下一位数字较小, 所以先讨论高位
{
last = i;
k = 1;
break;
}
else m -= f[n][i][1];
if (f[n][i][0] >= m)
{
last = i;
k = 0;
break;
}
else
m -= f[n][i][0];
}
vis[last] = 1;
ans.emplace_back(last);
for (int i = 2; i <= n; i++)
{
if (k == 1)
{
for (int j = 1; j < last; j++)
{
if (vis[j])
continue;
int rk = 1;
for (int p = 1; p < j; p++)//计算j在剩下的数字中是第几大, 因为f[1][][]统计的是数字范围为[1, i]的方案数
if (!vis[p])
rk++;
if (f[n - i + 1][rk][0] >= m)
{
last = j;
k = 0;
vis[j] = 1;
ans.push_back(j);
break;
}
m -= f[n - i + 1][rk][0];
}
}
else
{
for (int j = last + 1; j <= n; j++)
{
if (vis[j])
continue;
int rk = 1;
for (int p = 1; p < j; p++)
if (!vis[p])
rk++;
if (f[n - i + 1][rk][1] >= m)
{
last = j;
k = 1;
vis[j] = 1;
ans.push_back(j);
break;
}
m -= f[n - i + 1][rk][1];
}
}
}
for (auto it : ans)
cout << it << ' ';
cout << '\n';
}
signed main()
{
IOS;
int t = 1;
cin >> t;
while (t--)
solve();
return 0;
}
P7690 [CEOI2002] A decorative fence(dp, 排列大小),dp4
于 2022-09-03 13:41:49 首次发布