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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。