码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #259 (Div. 1)——Little Pony and Harmony Chest

时间:2014-08-02 12:56:33      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:acm   状压dp   

题目连接

  • 题意:
    给n个整数ai,求一个序列bi,使得b序列中任意两个数互质,而且sigma(abs(ai - bi))最小,输出任意一个b序列即可
     (1?≤?n?≤?100 (1?≤?ai?≤?30)
  • 分析:
    首先明确一点,题目没有限制b的范围。。。。为此wa了好多次,不过可以推断出来,b肯定小于等于60
    任意两个数互质,也就是说,对于新加入的一个bi,如果知道了之前所有数的质因子,那么当前数只要没有这个质因子就是一种满足的情况。而60以内的质数不到20个,所以直接状压DP即可。DP[i][j],表示处理到第i个数,所含的质因子为j(二进制形式)
const int MAXN = 60;
const int SIZE = 16;

int ipt[110];
int dp[110][1 << SIZE];
int p[110][1 << SIZE];
int x[110][1 << SIZE];
int to[MAXN + 1];
int prime[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53};
map<int, int> mp;

void init()
{
    REP(i, SIZE)
        mp[prime[i]] = 1 << i;
    FE(ii, 0, MAXN)
    {
        int n = ii, ret = 0, i;
        for (i = 0; i < SIZE && prime[i] * prime[i] <= n; i++)
            if (n % prime[i] == 0)
            {
                while (n % prime[i] == 0)
                    n /= prime[i];
                ret += 1 << i;
            }
        if (n > 1)
            ret += mp[n];
        to[ii] = ret;
    }
}

int n;
void dfs(int idx, int id)
{
    if (idx >= 2)
        dfs(idx - 1, p[idx][id]);
    printf("%d%c", x[idx][id], idx == n ? '\n' : ' ');
}

int main ()
{
    int all = 1 << SIZE;
    init();
    while (~RI(n))
    {
        FE(i, 1, n)
            RI(ipt[i]);
        CLR(dp, INF); dp[0][0] = 0;

        FE(i, 0, n - 1)
        {
            FF(j, 0, all)
            {
                FE(jj, 0, MAXN)
                {
                    int v = to[jj];
                    if (j & v)
                        continue;
                    int val = dp[i][j] + abs(jj - ipt[i + 1]);
                    int& nxt = dp[i + 1][j | v];
                    if (val < nxt)
                    {
                        nxt = val;
                        p[i + 1][j | v] = j;
                        x[i + 1][j | v] = jj;
                    }
                }
            }
        }
        int ans = INF, id = 0;
        REP(j, all)
        {
            if (dp[n][j] < ans)
            {
                ans = dp[n][j];
                id = j;
            }
        }
        dfs(n, id);
    }
    return 0;
}


Codeforces Round #259 (Div. 1)——Little Pony and Harmony Chest,布布扣,bubuko.com

Codeforces Round #259 (Div. 1)——Little Pony and Harmony Chest

标签:acm   状压dp   

原文地址:http://blog.csdn.net/wty__/article/details/38346251

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!