Little Pony and Harmony Chest CF4538 (状态压缩dp)

经典状态压缩dp

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#define min(x,y) (x>y?y:x)
using namespace std;
int factor[30],all,n,a[105],b[105][1<<17],pre[105][1<<17],s1,s0,f[105][1<<17],ansk;
bool pd[80];
void print(int i,int k)
{
    if(i==0) return;
    print(i-1,pre[i][k]);
    if(i==n) printf("%d",b[i][k]); else printf("%d ",b[i][k]);
    return;
}
int main()
{
    pd[1]=1;
    for(int i=2; i<=60; i++)
    if(!pd[i]){
        factor[++all]=i;
        for(int j=2; i*j<=60; j++)
            pd[i*j]=1;
    }
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
        scanf("%d",&a[i]);
    memset(f,127,sizeof(f));
    for(int i=0; i<=(1<<16)-1; i++)
        f[0][i]=0;

    int ans=10000000;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=59; j++)
        {
            s1=(1<<16)-1;
            for(int k=1; k<17; k++)
                if(j%factor[k]==0) s1=s1^(1<<(k-1));
            s0=s1^((1<<16)-1);
            for(int k=0; k<=(1<<16)-1; k++)
            {
                int p0=k&s1,p1=(k&s1)+s0;
                if(f[i][p1]>f[i-1][p0]+abs(a[i]-j))
                {
                    f[i][p1]=f[i-1][p0]+abs(a[i]-j);
                    b[i][p1]=j;
                    pre[i][p1]=p0;
                }
                if(i==n&&ans>f[n][p1])
                {
                    ans=f[n][p1];
                    ansk=p1;
                }
            }
        }
    print(n,ansk);
    return 0;
}

Little Pony and Harmony Chest CF4538 (状态压缩dp)

时间: 2024-10-09 18:20:43

Little Pony and Harmony Chest CF4538 (状态压缩dp)的相关文章

Codeforces 453B Little Pony and Harmony Chest:状压dp【记录转移路径】

题目链接:http://codeforces.com/problemset/problem/453/B 题意: 给你一个长度为n的数列a,让你构造一个长度为n的数列b. 在保证b中任意两数gcd都为1的情况下,使得 ∑|a[i]-b[i]|最小. 让你输出构造的数列b. (1<=n<=100, 1<=a[i]<=30) 题解: 因为1<=a[i]<=30,所以有1<=b[i]<=60,此时才有可能最优. 因为b中任意两数gcd为1,所以对于一个质因子p[i]

Codeforces Round #259 (Div. 2) D. Little Pony and Harmony Chest 状压DP

D. Little Pony and Harmony Chest Princess Twilight went to Celestia and Luna's old castle to research the chest from the Elements of Harmony. A sequence of positive integers bi is harmony if and only if for every two elements of the sequence their gr

Codeforces Round #259 (Div. 2)-D. Little Pony and Harmony Chest

题目范围给的很小,所以有状压的方向. 我们是构造出一个数列,且数列中每两个数的最大公约数为1; 给的A[I]<=30,这是一个突破点. 可以发现B[I]中的数不会很大,要不然就不满足,所以B[I]<=60左右.构造DP方程DP[I][J]=MIN(DP[I][J],DP[I][J^C[K]]+abs(a[i]-k)); K为我们假设把这个数填进数组中的数.同时开相同空间记录位置,方便输出结果.. #include<iostream> #include<stdio.h>

codeforces 453 B Little Pony and Harmony Chest (状压dp)

题目大意: 需要你构造一个b数组.使得b数组中的所有元素互质. 而且使得b数组与a数组中的每个对应下标元素的差值和最小. 思路分析: 考虑到 a中所有元素都是 0 - 30. 所以b中的元素也只可能在 0 - 59. 因为如果b 选择60的话,结果和1是一样的,而且b序列中 1 可以重复出现很多次. 因为gcd (1,x) = 1.. 所以们首先把2 - 59中的所有素数处理出来,只有17个. 然后状压这些素数因子. dp[i] [s] [0] 表示 递推到第 i 个位置 达到素数因子为s的状态

Codeforces 454D - Little Pony and Harmony Chest

454D - Little Pony and Harmony Chest 思路: 状压dp,由于1的时候肯定满足题意,而ai最大是30,所以只要大于等于59都可以用1替换,所以答案在1到59之间 然后筛出1到58之间的质数,只有16个,把1到58的数的状态由这16个质数表示,如果整除这个质数则二进制中这一位为1,否则则为0 状态:dp[i][j]表示到第i个数为止选取的数的状态为j的最小差和 初始状态:dp[0][0]=0 状态转移: dp[i+1][j|sta[k]]=min(dp[i+1][

Codeforces 453B Little Pony and Harmony Chest(状压)

题目链接:Codeforces 453B Little Pony and Harmony Chest 题目大意:给定一个序列a, 求一序列b,要求∑|ai?bi|最小.并且b中任意两数的最大公约束为1. 解题思路:因为b中不可能含有相同的因子,所以每个素数只能使用1次.又因为说ai最大为30,所以素数只需要考虑到57即可.因为即使对于30而言,59和1的代价是一样的. 所以有dp[i][j]表示的是到第i个数,使用过的素数j. #include <cstdio> #include <cs

Codeforces 453B Little Pony and Harmony Chest 状压dp

题目链接:点击打开链接 b的数字最多只能达到59,因为选>=60 不如选1 所以状压一下前面出现过的素数即可,在59内的素数很少 然后暴力转移.. #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <string.h> const int Inf = (int)(1e9); const int S = 1 <<

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

题目连接 题意: 给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]

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反