国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

最大子段和,二分法變異,動態規劃

2019-11-08 18:49:39
字體:
來源:轉載
供稿:網友

先描述“最大子段和”的概念,然后用分治法和動態規化來解決,最后添加一些功能。

對于n個元素的整數數列(可能還有負整數),求任意連續m個數(m<=n),使其和為最大。如果該子段均為負數,定義其和為0.

比如{-2 11 -4 13 -5 -2},的最大子段和為{11,-4,13},其和為20。

該問題不能采用簡單的分治法來解決,比如上面的數組分成{-2,11,-4}和{13,-5,-2}后,一個子問題的解是11,另一個是13,然而都不可能達到最終解。

所以這個問題的兩個子問題不是相互獨立的,需要涉及子問題的交互。故采用變異的二分法來處理。

 intmaxSub_binary(constvector<int>&nums,intleft,intright){

   if(left==right)returnnums[left]> 0 ? nums[left]: 0;//處理只有一個數字的情況。

   intmid = (left + right)>> 1;//分為兩部分

   intmaxSum_left = maxSub_binary(nums,left,mid);//左邊遞歸求解

   intmaxSum_right = maxSub_binary(nums, mid +1, right);//右邊遞歸求解

    //處理腳踩兩條船的子段

   intleftSum(0);

   for(inti(mid), tmpSum(0); i >= left; --i) {

       tmpSum+= nums[i];

       if(tmpSum > leftSum)leftSum = tmpSum;

   }//fori

   intrightSum(0);

   for(inti(mid + 1), tmpSum(0); i <= right; ++i) {

       tmpSum+= nums[i];

       if(tmpSum > rightSum)rightSum = tmpSum;

   }//fori

    //比較子段和的大小,選擇返回哪一部分的子段和

   intmaxSum_twoParts = leftSum + rightSum;

   if(maxSum_twoParts < maxSum_left&&maxSum_right < maxSum_left)returnmaxSum_left;

   if(maxSum_twoParts < maxSum_right)returnmaxSum_right;

   returnmaxSum_twoParts;

}//maxSub_binary

如果分治法的子問題不能相互獨立,也就是子問題相互重疊的情況,一般采用動態規劃法來解決。

int maxSub_dp(constvector<int>&nums) {

   intret(0);

   intlen = (int)nums.size();

   vector<int>dp(len, 0);

   dp[0]=nums[0];

   for(inti(1); i < len; ++i) {

       if(dp[i - 1]> 0)dp[i]= dp[i - 1]+nums[i];

       elsedp[i]=nums[i];

       if(dp[i]> ret)ret = dp[i];

   }//fori

   returnret;

}//maxSub_dp

下面的代碼在之前函數的基礎上,進一步得到最大子段和的長度,注意長度信息的添加位置。

由于maxSub_len_binary的返回值用來返回最大子段和的值,只能將長度信息反映在一個引用參數curLen上了。

maxSub_len_dp也是類似處理。

int maxSub_len_binary(constvector<int> &nums,intleft,intright,int&curLen) {

   if(left==right) {

       curLen= 1;

       returnnums[left]> 0 ? nums[left]: 0;

   }//if

   intmid = (left + right)>> 1;

   intleftLen(0);

   intmaxSum_left = maxSub_len_binary(nums,left,mid, leftLen);

   intrightLen(0);

   intmaxSum_right = maxSub_len_binary(nums, mid +1, right, rightLen);

   intleftSum(0), leftPartLen(0);

   for(inti(mid), tmpSum(0), tmpPartLen(0); i >= left;--i) {

       tmpSum+= nums[i];

       ++tmpPartLen;

       if(tmpSum > leftSum)leftSum = tmpSum, leftPartLen = tmpPartLen;

   }//fori

   intrightSum(0), rightPartLen(0);

   for(inti(mid + 1), tmpSum(0), tmpPartLen(0); i <= right;++i) {

       tmpSum+= nums[i];

       ++tmpPartLen;

       if(tmpSum > rightSum)rightSum = tmpSum, rightPartLen = tmpPartLen;

   }//fori

   intmaxSum_twoParts = leftSum + rightSum;

   if(maxSum_twoParts < maxSum_left&&maxSum_right < maxSum_left) {

       curLen= leftLen;

       returnmaxSum_left;

   }//if

   if(maxSum_twoParts < maxSum_right) {

       curLen= rightLen;

       returnmaxSum_right;

   }//if

   curLen= leftPartLen + rightPartLen;

   returnmaxSum_twoParts;

}//maxSub_len_binary

 

int maxSub_len_dp(constvector<int> &nums,int&curLen) {

   intret(0);

   intlen = (int)nums.size();

   vector<int>dp(len, 0);

   dp[0] = nums[0];

   inttmpLen(1);

   for(inti(1); i < len; ++i) {

       if(dp[i - 1] > 0)dp[i] = dp[i - 1] +nums[i],++tmpLen;

       elsedp[i] =nums[i], tmpLen = 1;

       if(dp[i] > ret)ret = dp[i],curLen =tmpLen;

   }//fori

   returnret;

}//maxSub_len_dp




發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 柏乡县| 壤塘县| 洞口县| 乐陵市| 庆云县| 乌审旗| 新民市| 堆龙德庆县| 临泽县| 阜新市| 衢州市| 许昌市| 四子王旗| 桐乡市| 余姚市| 会昌县| 岳西县| 都江堰市| 青铜峡市| 永登县| 慈利县| 南陵县| 宜川县| 汉川市| 阿克陶县| 册亨县| 景宁| 灌阳县| 金秀| 百色市| 仙桃市| 广河县| 麻城市| 杨浦区| 夏津县| 云龙县| 邛崃市| 固阳县| 福鼎市| 略阳县| 红原县|