考慮值為6的石頭:將值為6的石頭分為兩部分,一部分均分為兩堆,另一部分用於填補缺口。
所謂填缺口就是當其他的石頭分完之後再把這部分石頭分入兩堆(也有可能只放入一堆)。
現在考慮需要多少6值石頭用於填缺口。
假設左邊的總值小於右邊的總值
1.要能均分,剩下的缺口一定是6的倍數;
2.在分配其他的石頭時,可以做到盡可能的是缺口小
(比如,如果可以在右邊找到幾個石頭使它們的值之和為6,可以把它們勻給左邊);
3.當不能再從右邊勻給左邊時,可能出現的缺口在大是多少?(缺口大小確定了就可以確定需要的用於填缺口的石頭數量)
缺口可能是30(右邊剛好比左邊多6個5值石頭)
缺口可能是是36?
能得到的最小缺口不可能是36,因為總能勻幾個石頭使缺口小於36。
所以對於6值石頭,最多需要5個來填缺口,其餘均分即可。
對於其他值的石頭,可以採用同樣的分析;
值 需要用於填缺口的數量
1 6
2 5
3 5
4 5
5 6
6 5
統一一下
1 6
2 6
3 6
4 6
5 6
6 6
留下需要填補缺口的石頭,把剩下的石頭(偶數個)均分為兩堆
需要考慮的也只是用來填缺口的石頭。
if(marbles[i]>6)
多餘的值根本沒有意義,就像消消樂那樣,只要去掉那些能自己對消掉,留下至少能填補其他缺口的就行,6這個值說實話我至今不太明白,我原本的想法是取1,2,3,4,5,6的公倍數,留下至少60應該就可以了,也許是我考慮不太周全,結果是錯的,上面貼的那些想法按我自己理解,應該是取最少的需要留下填補缺口的數量,2和3互補至少要留3個,3和4互補至少要留4個,4和5互補至少要留5個,5和6互補至少要留6個,1和6也是6個,綜上,要留出足夠的彈珠能夠填補缺口的需要。可能解釋得不太清楚,大家可以去poj翻翻這個題目的討論區
ac**:
#include#include#includeint a[7];
int dfs(int value)
int i;
for(i=7;i>0;i--)
a[i]--;
if(dfs(value-i)==1)
a[i]++;
} return 0;
}int main()
sum=sum+a[i]*i;
} while(sum!=0)
else
else
} for(i=1,sum=0;i<7;i++)
sum=sum+a[i]*i;
}} return 0;
}
部分揹包 poj1014 Dividing
一種物品,限制了數量,那就不能按照完全揹包的寫法去寫了 如果按照01揹包的方法去寫,如果數量很大,那麼必然會超時,那有沒有什麼好辦法呢?我們先講神奇的二進位制思想 我們都知道,任何乙個十進位制都能轉換成二進位制 廢話 那麼二進位制就會對應著許多二進位 還是廢話 每個二進位都是2的倍數 肯定啊 所以反...
POJ 1014 Dividing 母函式優化
description 每一行輸入6個數,第i個數表示價值為i的珠寶的個數,問這些珠寶是不是能等價平分給兩個人。sample input 1 0 1 2 0 0 1 0 0 0 1 1 0 0 0 0 0 0 sample output collection 1 can t be divided.c...
POJ 1014 Dividing 多重揹包問題
這題做了將近乙個月,斷斷續續的看揹包問題,今天總於一口氣把揹包九講中的前三講看完了。為什麼這樣正確呢?證明 1 數列1,2,4,2 k 1 n 2 k 1中所有元素的和為n,所以若干元素的和的範圍為 1,n 2 如果正整數t 2 k 1,則t一定能用1,2,4,2 k 1 中某幾個數的和表示,這個很...