codeforces 558C 分类: codeforces 2015-08-08 14:15 9人阅读 评论(0) 收藏


将每个数转成二进制的形式,可以发现对每个数的操作只会使二进制数中的 ‘1’减少,

而有效的目标状态一定不大于 max{a[i]}, 所以每个数能扩展出的有效状态只有 2*log max{a[i]} 种,而这个范围是非常小的。。。

可以用搜索处理出每个数能扩展出的有效状态以其代价。

最后枚举目标状态,更新答案即可。



#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <string>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <utility>
#include <iostream>
#include <algorithm>

template<class Num>void read(Num &x)
{
    char c; int flag = 1;
    while((c = getchar()) < '0' || c > '9')
        if(c == '-') flag *= -1;
    x = c - '0';
    while((c = getchar()) >= '0' && c <= '9')
        x = (x<<3) + (x<<1) + (c-'0');
    x *= flag;
    return;
}
template<class Num>void write(Num x)
{
    if(x < 0) putchar('-'), x = -x;
    static char s[20];int sl = 0;
    while(x) s[sl++] = x%10 + '0',x /= 10;
    if(!sl) {putchar('0');return;}
    while(sl) putchar(s[--sl]);
}

const int maxn = 1e5 + 5, size = 1e5 + 5;
const int Nya = -1, INF = 0x3f3f3f3f;
#define REP(__i,__st,__ed) for(int __i = (__st); __i <= (__ed); i++)
#define update(x, y) x = std::min(x, y)

int a[maxn], maxa;
int cnt[size], cost[size];
int n, ans = INF;

std::queue<int> line;
std::vector<std::pair<int,int> > vis;

int find(int x) 
{
    for(int i = vis.size() - 1; i >= 0; i--)
        if(vis[i].first == x) return i;
    return Nya; 
}
void newrc(int t, int c)
{
    if(t > maxa) return;

    int pos = find(t);

    if(pos == Nya)
    {
        vis.push_back(std::make_pair(t, c));
        line.push(vis.size() - 1);
    }
    else
    {
        if(c < vis[pos].second)
        {
            vis[pos].second = c;
            line.push(pos);
        }
    }
}
void calcu(int f)
{
    vis.clear();

    vis.push_back(std::make_pair(f, 0));
    line.push(0);

    while(!line.empty())
    {
        int x = line.front();
        line.pop();

        newrc(vis[x].first << 1, vis[x].second + 1);
        newrc(vis[x].first >> 1, vis[x].second + 1);
    }

    REP(i, 0, vis.size() - 1)
    {
        cnt[vis[i].first] ++;
        cost[vis[i].first] += vis[i].second;
    }
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("C.in","r",stdin);
    freopen("C.out","w",stdout);
#endif

    read(n);

    REP(i, 1, n) read(a[i]), maxa = std::max(maxa, a[i]);

    REP(i, 1, n) calcu(a[i]);

    REP(i, 0, maxa) if(cnt[i] == n) update(ans, cost[i]);

    write(ans);

#ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
#endif
    return 0;       
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-08-08 14:15  <Dash>  阅读(108)  评论(0编辑  收藏  举报