CF1342F Make It Ascending
Posted handlip
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1342F Make It Ascending相关的知识,希望对你有一定的参考价值。
题目
给你一个长度为 (n) 的数列 (a_1,a_2, cdots ,a_n)。你可以执行以下操作:选择一对 (i,j)((i e j)),使 (a_i) 变为 (a_i+a_j) 并在数列中删去 (a_j)。问最少执行多少次操作,可以使得数列严格上升,并给出一种方案。
数据范围
(n le 15)
时限:7s
代码
# include <bits/stdc++.h>
using namespace std;
const int MAXN = 15 + 5;
const int MAX1 = (1 << 15) + 5;
const int INF = 1e9;
int n;
int a[MAXN], pos[MAXN];
int sum[MAX1];
int dp[MAXN][MAXN][MAX1];
struct DPIdx
{
int i, j, mask;
} mem[MAXN][MAXN][MAX1];
int main()
{
int ncase;
scanf("%d", &ncase);
while (ncase--)
{
scanf("%d", &n);
for (int i = 0; i < n; ++i)
{
scanf("%d", &a[i]);
}
for (int mask = 0; mask < (1 << n); ++mask)
{
sum[mask] = 0;
for (int i = 0; i < n; ++i)
{
if ((1 << i) & mask)
{
sum[mask] += a[i];
}
}
for (int i = 0; i <= n; ++i)
{
for (int j = 0; j <= n; ++j)
{
dp[i][j][mask] = INF;
}
}
}
dp[0][0][(1 << n) - 1] = 0;
for (int i = 0; i < n; ++i)
{
pos[i] = i + 1;
}
DPIdx ans;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
for (int mask = (1 << n) - 1; mask; --mask)
{
if (dp[i][j][mask] != INF)
{
for (int sub = mask; sub; sub = (sub - 1) & mask)
{
if ((sub >> j) && sum[sub] > dp[i][j][mask] && sum[sub] < dp[i + 1][j + 1 + __builtin_ctz(sub >> j)][mask ^ sub])
{
dp[i + 1][j + 1 + __builtin_ctz(sub >> j)][mask ^ sub] = sum[sub];
mem[i + 1][j + 1 + __builtin_ctz(sub >> j)][mask ^ sub] = {i, j, mask};
if ((mask ^ sub) == 0)
{
ans = {i + 1, j + 1 + __builtin_ctz(sub >> j), mask ^ sub};
}
}
}
}
}
}
}
printf("%d
", n - ans.i);
while (ans.i != 0)
{
DPIdx fa = mem[ans.i][ans.j][ans.mask];
for (int i = 0; i < n; ++i)
{
if (((1 << i) & (ans.mask ^ fa.mask)) && i != ans.j - 1)
{
printf("%d %d
", pos[i], pos[ans.j - 1]);
for (int j = i + 1; j < n; ++j)
{
--pos[j];
}
}
}
ans = fa;
}
}
return 0;
}
以上是关于CF1342F Make It Ascending的主要内容,如果未能解决你的问题,请参考以下文章
Given an array where elements are sorted in ascending order, convert it to a height balanced BST.(示例