标签:
大意是有一排石子,每一堆有a[i]个,目标状态每一堆有b[i]个,每一步可以从一堆中取出一个石子转移到相邻的一个,其中1和n也算相邻也即环形。问最少步数。
比赛的时候写了个按照步数贪心的做法,FST了,当时想的贪心是从1到n/2枚举步数,for每一个需要石子的堆i,从(i+d)%n与(i-d)%n中看是否可以转移。
比赛结束自己想到一个反例
1 0 1 0 0
0 1 0 1 0
答案应当是2,但是我那个贪心结果会成3。
后来看了下别人做法,大致有2种,一种是最优解中会存在某些点,这些点不会有穿越他们的MOVE,所以可以枚举每个点作为开始,将环形转为线性。
答案是每个a与b的前缀和之差的和。
还有一种做法是做一个c[i]=a[i]-b[i]的数组,sort之后,取中位数作为target。答案是所有值与中位数之差的和。
下面贴第一种解法的代码
1 class MoveStones 2 { 3 public: 4 long long get(vector <int> a, vector <int> b) { 5 long long s1=0,s2=0; 6 int n=a.size(); 7 for (int i=0;i<n;i++) { 8 s1+=a[i]; 9 s2+=b[i]; 10 } 11 if (s1!=s2) return -1; 12 long long ret=1LL<<62; 13 for (int i=0;i<n;i++) { 14 long long now=0,s=0; 15 for (int j=0;j<n;j++){ 16 s+=a[j]-b[j]; 17 now+=abs(s); 18 } 19 ret=min(ret,now); 20 rotate(a.begin(),a.begin()+1,a.end()); 21 rotate(b.begin(),b.begin()+1,b.end()); 22 } 23 return ret; 24 } 25 };
标签:
原文地址:http://www.cnblogs.com/micrari/p/5229344.html