回溯算法之幸运的袋子
解法框架
【README】回溯算法基本框架
幸運(yùn)的袋子(點(diǎn)擊跳轉(zhuǎn))
這道題基本也是回溯,題解中有一部分提到了dfs,其實(shí)dfs本質(zhì)也是回溯算法。這道題有點(diǎn)特別,除了考察算法外,還輕微涉及一點(diǎn)數(shù)學(xué)知識,其實(shí)也可以說是規(guī)律吧。此題本質(zhì)就是在集合中找到符合條件的子集,這條件就是子集中所有數(shù)字的和大于所有數(shù)字的積
規(guī)律如下
首先,這道題要完全自己輸入和輸出,先打起框架。咋們的選擇列表,也就是所有球的編號,依次存放在一個(gè)vector中,接著將球按照編號從小到大的排序
#include <iostream> #include <vector> #include <algorithm> using namespace std;int main() {int n;//接受幾個(gè)球cin>>n;vector<int> ball;for(int i=0;i<n;i++){int temp;cin>>temp;ball.push_back((temp));}sort(ball.begin(),ball.end());//排序}選擇列表有了,下一個(gè)就是路徑,這個(gè)路徑非常簡單,只需要一個(gè)整型ret即可,因?yàn)楫?dāng)sum>multi的時(shí)候,這表明現(xiàn)在就已經(jīng)可以作為一個(gè)幸運(yùn)的袋子了,所以ret增加。 所以將ret設(shè)置為全局變量。
對于遞歸函數(shù),第一個(gè)參數(shù)一定是選擇列表,第二個(gè)參數(shù)是球的個(gè)數(shù),第三個(gè)參數(shù)要設(shè)置為一個(gè)pos,因?yàn)檫f歸函數(shù)進(jìn)行for循環(huán)時(shí)一定要一個(gè)正確的起始位置,for循環(huán)每次就從i=pos的位置,遞歸時(shí)這個(gè)球加入了,我們就pos=i+1,表明選擇下一個(gè)球。剩下兩個(gè)參數(shù)分別為sum和multi用于計(jì)算判斷
int ret=0;//幸運(yùn)的袋子個(gè)數(shù) void back(vector<int>& ball,int n,int pos,int sum,int multi) {for(int i=pos;i<n;i++){sum+=ball[i];//和multi*=ball[i];//乘積if(sum>multi)//ball[i]這個(gè)球加入后符合幸運(yùn)袋子{ret+=1;back(ball,n,i+1,sum,multi);//繼續(xù)回溯,下一個(gè)位置}else if(ball[i]==1)//如果不滿足條件,但是這一位是1,是還有機(jī)會的,所以遞歸就可以了{back(ball,n,i+1,sum,multi);}else{break;//不滿足直接退出}sum-=ball[i];//撤銷選擇multi/=ball[i];//撤銷選擇while(i<n-1 && ball[i]==ball[i+1])//連續(xù)的只選擇1次{++i;}}}需要注意的是去重要寫在后面,不要一上來就去重
最后完善即可,注意multi在傳入時(shí)要傳入1,不要傳入0
#include <iostream> #include <vector> #include <algorithm> using namespace std;int ret=0;//幸運(yùn)的袋子個(gè)數(shù) void back(vector<int>& ball,int n,int pos,int sum,int multi) {for(int i=pos;i<n;i++){sum+=ball[i];//和multi*=ball[i];//乘積if(sum>multi)//ball[i]這個(gè)球加入后符合幸運(yùn)袋子{ret+=1;back(ball,n,i+1,sum,multi);//繼續(xù)回溯,下一個(gè)位置}else if(ball[i]==1)//如果不滿足條件,但是這一位是1,是還有機(jī)會的,所以遞歸就可以了{back(ball,n,i+1,sum,multi);}else{break;//不滿足直接退出}sum-=ball[i];//撤銷選擇multi/=ball[i];//撤銷選擇while(i<n-1 && ball[i]==ball[i+1])//連續(xù)的只選擇1次{++i;}} }int main() {int n;//接受幾個(gè)球cin>>n;vector<int> ball;for(int i=0;i<n;i++){int temp;cin>>temp;ball.push_back((temp));}sort(ball.begin(),ball.end());//排序back(ball,n,0,0,1);cout<<ret<<endl;return 0;}總結(jié)
以上是生活随笔為你收集整理的回溯算法之幸运的袋子的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows菜单
- 下一篇: Linux系统编程3:基础篇之详解Lin