整數拆分問題(1)

2021-07-25 18:41:45 字數 1539 閱讀 7697

題意:給你乙個n,求滿足1/x+1/y=1/n的x,y種類數

當你看到這題的時候,你會怎麼做呢?

當時我看到第一反應就是先化簡,因為1/x這個數肯定是比1小的小數,這個精度問題是個大問題,而且兩個小數相加也不會完全等於那個小數。所以,想辦法劃成整數關係式。

兩邊同乘xy,得

y+x=xy/n

轉換,得    

n=xy/(x+y)

然後直接求嗎?不不不,n是個整數,難道你就能保證右邊除出來是整數嗎?!

然後,絞盡腦汁,沉思,深呼吸,學下一休哥,忽然想到了!

你可以保證,當兩個分數相加要等於乙個分數時,兩個分數的分母肯定都大於這個分數的分母,也就是x,y>n

我們可以假設,

x=n+u,y=n+v

, 其中u,v肯定都是大於0的整數

然後代入,簡化出來,不可思議,

n^2=uv

而乙個整數n都是可以拆成 

n=p1^a1 * p2^a2 *……*pn^an 

的形式

此時n拆成兩個數相乘的形式的種類個數是

(a1+1)*(a2+1)*……*(an+1)

【不細講了,你可以自己去寫幾個找找規律】 那麼

n^2=p1^2a1 * p2^2a2 *……*pn^2an

此時,種類數即為

(2a1+1)*(2a2+1)*……*(2an+1)  

這個問題就迎刃而解了,接下來就是求底和冪的事情了。

需要特別注意的是

當n<2時,是無法整數拆分的,也就是種類數為0

#include #include using namespace std; 

#define maxi 20

struct yinshu

; struct div

; div getpn(int m);

void vout(div pn);

yinshu getone(int yin,int& m);

int main()

return 0;

} div getpn(int m)

int uplimit=(int)sqrt(m*1.0);

i=2;

j=0;

while(i<=uplimit)

i++;

} if(m>1)

pans.xiangshu=j;

return pans;

} void vout(div pn)

{ int i;

int ans=1;

for(i=0;i

整數拆分問題

問題 對於1個正整數n,將其拆分成幾個正整數的和,如何拆分可使得其乘積最大?csdn使用者pathuang68給出的結論是 如果不在乎是否為整數的話,那麼把每份平均分為e 2.71828459045.時,所得到的乘積是最大的,如果要是整數的話,那麼就選盡可能地靠近e的整數即可,比如3。具體證明請參見...

整數拆分問題 遞迴法

整數劃分問題是演算法中的乙個經典命題之一,有關這個問題的講述在講解到遞迴時基本都涉及到。所謂整數劃分,是指把乙個正整數n寫成如下形式 n m1 m2 m3 mi 其中mi為正整數,並且1 mi n 則為n的乙個劃分。如果中的最大值不超過m,即max m,則稱它屬於n的乙個m劃分。這裡我們記n的m劃分...

回溯演算法 整數拆分問題

洛谷p2404.簡單的回溯法實現,輸入乙個數字n,求出1到n 1中相加和是n的算式。用乙個ans陣列儲存探索到的每乙個數字,在dfs函式中用減法的形式得到和什麼時候到達了n,到達n也就是temp變為0的時候。同時又根據例項,沒有重複的算式,乙個數字可以用多次,所以i的起始位置要設定乙個start來表...