首页 > 其他 > 详细

[CodeForces 453B] Little Pony and Harmony Chest

时间:2021-05-03 18:42:20      阅读:36      评论:0      收藏:0      [点我收藏+]

https://codeforces.ml/contest/453/problem/B

题意:
给定序列\(a(1 \leq a_i \leq 30)\),求等长序列\(b\),满足\(b\)序列中任意两个数都是互质的,且\(\sum_1^n\lvert a_i - b_i\rvert\)尽量小。

思路:
互质要求两个数之间没有相同的质因子。一个首先的想法是1肯定能直接满足。看一下\(a_i\)的范围,发现如果\(b_i\)的值没有比\(2 * a_i\)小的时候,我们不如直接取\(1\)。由此确立了\(b_i\)的范围为\([1, 60)\)。小于\(60\)的素数只有\(16\)个,数据范围很小,考虑状压\(dp\),把拥有的质因数的情况压缩一下,发现就比较好写了,再记录下路径即可。

#include <bits/stdc++.h>

using namespace std;

#define endl "\n"

inline int rd() {
    int f = 0; int x = 0; char ch = getchar();
    for (; !isdigit(ch); ch = getchar()) f |= (ch == ‘-‘);
    for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘;
    if (f) x = -x;
    return x;
}

typedef long long ll;

const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e2 + 7;
const int M = (1 << 16);

int n, m = (1 << 16) - 1;
int prime[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53};
int a[N], b[N], sta[N];
int dp[N][M], path[N][M];

void init() {
    for (int i = 0; i < 16; ++i) {
        int f = prime[i];
        for (int j = f; j < 60; j += f) {
            sta[j] |= 1 << i;
        }
    }
    memset(dp, 0x3f, sizeof(dp));
}

void solve() {
    n = rd();
    init();
    for (int i = 1; i <= n; ++i) {
        a[i] = rd();
    }
    dp[0][0] = 0;
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j <= m; ++j) {
            for (int k = 1; k < 60; ++k) {
                if ((sta[k] & j) == 0) {
                    int to = j | sta[k];
                    if (dp[i][to] > dp[i - 1][j] + abs(a[i] - k)) {
                        dp[i][to] = dp[i - 1][j] + abs(a[i] - k);
                        path[i][to] = k;
                    }
                }
            }
        }
    }
    int s = 0;
    int minn = inf;
    for (int j = 0; j <= m; ++j) {
        if (dp[n][j] < minn) {
            minn = dp[n][j];
            s = j;
        }
    }
    for (int i = n; i >= 1; --i) {
        b[i] = path[i][s];
        s -= sta[ path[i][s] ];
    }
    for (int i = 1; i <= n; ++i) {
        printf("%d%c", b[i], " \n"[i == n]);
    }
}

int main() {
    int t = 1;
    while (t--) solve();
    return 0;
}

[CodeForces 453B] Little Pony and Harmony Chest

原文:https://www.cnblogs.com/Sstee1XD/p/14727561.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!