日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

整数分区(求将整数拆分成任意个数正整数的方法个数)codewars 爆炸求和

發(fā)布時(shí)間:2023/12/14 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 整数分区(求将整数拆分成任意个数正整数的方法个数)codewars 爆炸求和 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

依舊是codewars上面的題目,獻(xiàn)上鏈接
codewars 爆炸總和

整數(shù)分區(qū)

整數(shù)n的分區(qū)是正整數(shù)(不一定是不同的)的無序集合,其加起來為n。這種分區(qū)的數(shù)量通常表示為p(n)。函數(shù)p稱為分區(qū)函數(shù),其值列表如下。這從p(0)= 1開始,因?yàn)橹挥幸粋€(gè)正整數(shù)的集合,其總和為零(即空集合)。

n:p(n)0:1 1:1 //12:2 //1+1 23:3 //1+1+1 1+2+1 34:5 //1+1+1+1 1+1+2 3+1 2+2 45:7 //1+1+1+1+1 1+1+1+2 1+1+3 1+2+2 4+1 2+3 56:11 //1+1+1+1+1+1 1+1+1+1+2 1+1+1+3 1+ 1+2+2 1+1+4 1+2+3 1+5 2+2+2 2+4 3+3 6...

數(shù)學(xué)規(guī)律

在寫代碼之前應(yīng)該先搞懂?dāng)?shù)學(xué)分區(qū)的數(shù)學(xué)規(guī)律。

假設(shè)將n進(jìn)行分區(qū),通過規(guī)律我們可以知道n各分區(qū)中包含n-1的分區(qū)加上1,整理之后得出以下規(guī)律:

p(n) = p(n-1)
+p(n-2) - p(n-2)中有“+1”的分區(qū)方法
+p(n-3) - p(n-3)中有“+1”的分區(qū)方法 - p(n-3)中有“+2”的分區(qū)方法

直到 n-i < i

p(n)12345678910
123571115223042
w[i][n]12345678910規(guī)律
+011111111111
+101235711152230p(n-1)
+20001122447w[i-1][n-1]-w[i-1][n-2]
+30000011122w[i-1][n-1]-w[i-1][n-3]
+40000000011w[i-1][n-1]-w[i-1][n-4]
+50000000001w[i-1][n-1]-w[i-1][n-5]
+iw[i-1][n-1]-w[i-1][n-i]


p(n)=∑w[i][n](0≤i≤(n+1)/2)p(n)=\sum w[i][n](0≤i≤(n+1)/2) p(n)=w[i][n](0i(n+1)/2)
找出規(guī)律之后我們就可以寫代碼了

代碼架構(gòu)

可以看出解決整數(shù)分區(qū)最重要的兩個(gè)函數(shù)一個(gè)是計(jì)算p(n)的求和公式,一個(gè)是計(jì)算w[n][i]的函數(shù)。

//p(n)加和函數(shù) using ull = unsigned long long; ull exp_sum(ull n) {ull num = 0;for (ull i = 0; i <= n/ 2; i++)//當(dāng)i>n/2,w[n][i]=0{num += cal_w(n, i);}sum_vec.push_back(num); return num; }//w[n][i]的計(jì)算函數(shù) ull cal_w(ull n, ull i) {if (n==0||i==0){return 1;}if (i==1){return sum_vec[n - 1];}if (i>n/2){return 0;}return add(n - 1, i - 1) - add(n - i, i - 1); };

在頁面上提交的時(shí)候發(fā)現(xiàn)有超時(shí),那么說明要改數(shù)據(jù)結(jié)構(gòu)了。
解決函數(shù)運(yùn)行性能,常常用內(nèi)存換運(yùn)行時(shí)間,也就是將以前計(jì)算過得數(shù)據(jù)存儲(chǔ)出來,方便使用。
加入兩個(gè)容器:

vector<ull>p{1,1,2}; vector<vector<ull>>w{ {0},{1},{1,1} };

代碼更改如下:

//前向聲明ull exp_sum(ull n); ull cal_w(ull n, ull i);//w[n][i]的計(jì)算函數(shù) ull cal_w(ull n, ull i) {if (n>=w.size())//如果w中沒有n的相關(guān)加和數(shù)據(jù),先進(jìn)行w[n]的計(jì)算{w.push_back(vector<ull>(n, 0));w.back()[0] = 1;w.back()[1] = p[n - 1];for (ull i = 2; i <= n / 2; i++){w.back()[i]= cal_w(n - 1, i - 1) - cal_w(n - i, i - 1);}}if (i>=w[n].size()&&i>n/2){return 0;}return w[n][i];//返回w[n][i] };//p(n)加和函數(shù) ull exp_sum(ull n) {while (n>=p.size()){ull num = 0;for (ull i = 0; i <= p.size()/ 2; i++)//p[n]不存在時(shí),先將n以及n以前的所有數(shù)據(jù)補(bǔ)齊{num += cal_w(p.size(), i);}p.push_back(num);}return p[n]; }

然后問題就完美解決了

貼上整數(shù)分區(qū)的值列表,可以用來調(diào)試

整數(shù)分區(qū)

總結(jié)

以上是生活随笔為你收集整理的整数分区(求将整数拆分成任意个数正整数的方法个数)codewars 爆炸求和的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。