題目:
有兩個序列a,b,大小都為n,序列元素的值任意整數,無序;
要求:通過交換a,b中的元素,使[序列a元素的和]與[序列b元素的和]之間的差最小。
例如:
var a=[100,99,98,1,2, 3];
var b=[1, 2, 3, 4,5,40];
解法一:
假設序列a,b中元素的和為sum_a和sum_b。假設aa和bb分別為序列a,b中的元素,則交換aa,bb後序列的和變為sum_a-aa+bb,sum_b+aa-bb;兩序列的差為(sum_a-aa+bb)-(sum_b+aa-bb)=sum_a-sum_b-2*(aa-bb);
所以可以掃瞄序列a,b中的元素,找到使abs(sum_a-sum_b-2*(aa-bb))最小的兩個元素進行交換,重複此過程,直至兩序列的差無法減小。
bool
swap2balance(
int*pa,
int*pb,
intn)
intdiff=suma-sumb;
while
(diff!=0)
} if(bestchange==0)
//差不能再縮小
return
false
; int
temp=pa[besti];
pa[besti]=pb[bestj];
pb[bestj]=temp;
suma-=bestchange;
sumb+=bestchange;
diff=suma-sumb;
} return
true
; }
解法二:
這個題目的原型是之前做過的acm動態規劃
多公尺諾骨牌(domino)
問題描述:有一種多公尺諾骨牌是平面的,其正面被分成上下兩部分,每一部分的表面或者為空,或者被標上1至6個點。現有一行排列在桌面上:
頂行骨牌的點數之和為6+1+1+1=9;底行骨牌點數之和為1+5+3+2=11。頂行和底行的差值是2。這個差值是兩行點數之和的差的絕對值。每個多公尺諾骨牌都可以上下倒置轉換,即上部變為下部,下部變為上部。
現在的任務是,以最少的翻轉次數,使得頂行和底行之間的差值最小。對於上面這個例子,我們只需翻轉最後乙個骨牌,就可以使得頂行和底行的差值為0,所以例子的答案為1。
這裡改變下輸入, a中的第i個元素和b中的第i個元素,構成第i組,所以輸入為乙個二維陣列input[2]
int input[2] = , , , , , };
可以使用乙個二維陣列,x為當前的組序號,y為這組能達到的差的值,其值為反轉的次數。
那麼可以預見,這是個稀疏矩陣,為了節省空間,採取三元組來儲存。
使用三元組記錄結果
typedef struct tagloc loc;
x記錄到目前的處理的組的序號。
y記錄計算出的上下兩組之間的差。
rev記錄要達到這組值翻轉的次數。
宣告乙個大陣列loc all[1000],記錄所有的可能性。
當x=0時,
如果不翻轉0組,那麼有y = 99, rev = 0
如果翻轉0組,那麼有y=-99, rev =1。
當x=n的時候,
遍歷陣列all中x=n-1的元素,即上一組的所有可能的值。
對於每個可能值 all[m] (all[m].x = n-1)
如果不翻轉n組,那麼有 x = n, y = all[m].y + (input[i][0]-input[i][1]) , rev = all[m].rev
如果翻轉第n組,那麼有 x = n, y = all[m].y - (input[i][0]-input[i][1]) , rev = all[m].rev+1
完成所有組後,對於最後一組x= 6,
all中的元素,當x=6時,y的絕對值最小的時候即經過rev次反轉上下兩組的最小差。
100題 32 兩個序列的和的差最小
有兩個序列a,b,大小都為n,序列元素的值任意整數,無序 要求 通過交換a,b 中的元素,使 序列a 元素的和 與 序列b 元素的和 之間的差最小。例如 var a 100,99,98,1,2,3 var b 1,2,3,4,5,40 2011年3月23日更新 感謝lambda2fei同學的提醒,下...
有兩個序列A和B,求k個最小的(ai bj)
題目 有兩個序列a和b,a a1,a2,ak b b1,b2,bk a和b都按公升序排列,對於1 i,j k,求k個最小的 ai bj 要求演算法盡量高效。解法一 看到這個題目,第乙個想法就是求出所有組合的加法結果,然後建立乙個大小為k的堆,利用這堆來求出最小的k個和值。那麼這種方法需要花費o k ...
求列表中兩個子串行之差最小的序列
def mean sorted list 題目 將乙個序列分成兩個子串行,確保兩者之間的差值最小 實現 1.對列表排序 2.遞迴列表 取出 1位置元素作為big,2 位置元素作為small,從前到後,切到 2位置 不包括 3.遞迴結束條件 傳入的引數為空,開始遞迴退層 4.乙個大列表b list,和...