POJ 1014 Dividing(深搜 剪枝)

2021-08-20 17:08:42 字數 1570 閱讀 2457

考慮值為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 中某幾個數的和表示,這個很...