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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

依舊是codewars上面的題目,獻上鏈接
codewars 爆炸總和

整數分區

整數n的分區是正整數(不一定是不同的)的無序集合,其加起來為n。這種分區的數量通常表示為p(n)。函數p稱為分區函數,其值列表如下。這從p(0)= 1開始,因為只有一個正整數的集合,其總和為零(即空集合)。

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...

數學規律

在寫代碼之前應該先搞懂數學分區的數學規律。

假設將n進行分區,通過規律我們可以知道n各分區中包含n-1的分區加上1,整理之后得出以下規律:

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

直到 n-i < i

p(n)12345678910
123571115223042
w[i][n]12345678910規律
+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)
找出規律之后我們就可以寫代碼了

代碼架構

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

//p(n)加和函數 using ull = unsigned long long; ull exp_sum(ull n) {ull num = 0;for (ull i = 0; i <= n/ 2; i++)//當i>n/2,w[n][i]=0{num += cal_w(n, i);}sum_vec.push_back(num); return num; }//w[n][i]的計算函數 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); };

在頁面上提交的時候發現有超時,那么說明要改數據結構了。
解決函數運行性能,常常用內存換運行時間,也就是將以前計算過得數據存儲出來,方便使用。
加入兩個容器:

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]的計算函數 ull cal_w(ull n, ull i) {if (n>=w.size())//如果w中沒有n的相關加和數據,先進行w[n]的計算{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)加和函數 ull exp_sum(ull n) {while (n>=p.size()){ull num = 0;for (ull i = 0; i <= p.size()/ 2; i++)//p[n]不存在時,先將n以及n以前的所有數據補齊{num += cal_w(p.size(), i);}p.push_back(num);}return p[n]; }

然后問題就完美解決了

貼上整數分區的值列表,可以用來調試

整數分區

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。