青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 30  文章 - 67  trackbacks - 0
<2013年6月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

常用鏈接

留言簿(8)

隨筆分類

隨筆檔案

文章檔案

收藏夾

Oops

搜索

  •  

積分與排名

  • 積分 - 86328
  • 排名 - 277

最新評論

閱讀排行榜

評論排行榜

 

今天主要是想回憶下DFS,所以就那全排列開刀了,自己寫了一個發現網上的解法真不錯就想總結下:

一、利用DFS實現(自己寫的)
廢話就不說了 上代碼:

#include <iostream>
#include 
<cstdio>
using namespace std;

const int size = 20;

bool visited[20];
int  arr[20];

int n;

void dfs(int cnt)
{
    
if( cnt == n)
    
{
        
for(int i = 0; i < n; ++i)
        
{
            cout 
<< arr[i] << " " ;
        }

        cout 
<< endl;
    }

    
else
    
{
        
for(int i = 1; i <= n; ++i )
        
{
            
if(!visited[i])
            
{
                arr[cnt] 
= i;
                visited[i] 
= 1;
                dfs(cnt
+1);
                visited[i] 
= 0;
            }

        }

    }

}



int main()
{

    
while(cin>>n)
    
{
        memset(visited, 
0sizeof(visited));
        dfs(
0);
    }


    
return 0;
}



這種方法,我沒有想好怎么實現含有相同元素的全全排列

二、利用遞歸實現,其實還是DFS,只是實現的方法不一樣,但是它能夠實現含有相同元素的全排列
下面給一段網上找的解釋,其實王曉東的那本《算法與設計》有這個:
令E={e1,e2...en}表示n個元素的集合,我們的目標是生成該集合的所有排列方式。令Ei為E中移去元素i以后所獲得的集合,perm(X)表示集合X中元素的排列方式,ei.perm(X)表示在perm(X)中的每個排列方式的前面均加上ei以后所得到的排列方式。例如,如果E={a,b,c},那么E1 = {b,c},perm(E1) = (bc,cb),e1.perm(E1) = (abc,acb)。

         對于遞歸的基本部分,采用n=1。當只有一個元素時,只可能產生一種排列方式,所以perm(E) = (e),其中e是E中的唯一元素。當n>1時,perm(E) = e1.perm(E1) + e2.perm(E2)+ e3.perm(E3)+.......+en.perm(En)。這種遞歸定義形式是采用n個perm(X)來定義perm(E),其中每個X包含n-1個元素。至此,一個完整的遞歸定義所需要的基本部分和遞歸部分都已完成。

下面給出我自己寫的代碼:

#include <iostream>
#include 
<cstdio>
using namespace std;

template
<class T>

void sswap(T &a, T &b)
{
    
if( a != b )
    {
        
int tmp = a;
        a 
= b;
        b 
= tmp;
    }
}

template
<class T>
void Perm(T list[], int k, int m)
{
    
if(k == m)
    {
        
for(int i = 0; i <= m; ++i)
        {
            cout 
<< list[i] << "";
        }
        cout 
<< endl;
    }
    
else
    {
        
for(int i = k; i <= m; ++i)
        {
           
// if( (list[k] != list[i]) || (k == i) ) //為了實現相同元素的全排
           
// {
                sswap(list[k], list[i]);
                Perm(list, k
+1, m);
                sswap(list[k], list[i]);
            
//}
        }
    }
}

int main()
{
    
int n;
    
int arr[10];

    
while(cin>>n)
    {
        
for(int i = 0; i < n; ++ i)
        {
            cin
>>arr[i];
        }

        Perm(arr, 
0, n - 1);
    }

    
return 0;
}



三、壓軸:STL next_permutation
 下面是網上的一段分析

C++/STL中定義的next_permutation和prev_permutation函數則是非常靈活且高效的一種方法,它被廣泛的應用于為指定序列生成不同的排列。本文將詳細的介紹prev_permutation函數的內部算法。

  按照STL文檔的描述,next_permutation函數將按字母表順序生成給定序列的下一個較大的排列,直到整個序列為降序為止。prev_permutation函數與之相反,是生成給定序列的上一個較小的排列。二者原理相同,僅遍例順序相反,這里僅以next_permutation為例介紹算法。

  先對序列大小的比較做出定義:兩個長度相同的序列,從兩者的第一個元素開始向后尋找,直到出現一個不同元素(也可能就是第它們的第一個元素),該元素較大的序列為大,反之序列為小;若一直到最后一個元素都相同,那么兩個序列相等。

  設當前序列為pn,下一個較大的序列為pn+1,這里蘊藏的含義是再也找不到另外的序列pm,使得pn < pm < pn+1。

  問題

  給定任意非空序列,生成下一個較大或較小的排列。

  過程

  根據上述概念易知,對于一個任意序列,最小的排列是增序,最大的為減序。那么給定一個pn要如何才能生成pn+1呢?先來看下面的例子:

  設3 6 4 2為pn,下一個序列pn+1應該是4 2 3 6。觀察第一個序列可以發現pn中的6 4 2已經為減序,在這個子集中再也無法排出更大的序列了,因此必須移動3的位置且要找一個數來取代3的位置。在6 4 2中6和4都比3大,但6比3大的太多了,只能選4。將4和3的位置對調后形成排列4 6 3 2。注意,由于4和3大小的相鄰關系,對調后產生的子集6 3 2仍保持逆序,即該子集最大的一種排列。而4是第一次移動到頭一位的,需要后面的子集為最小的排列,因此直接將6 3 2倒轉為2 3 6便得到了正確的一個序列pn+1。

  下面歸納分析該過程。假設一個有m個元素的序列pn,其下一組較大排列為pn+1:

  若pn的最后的2個元素構成一個最小的增序子集,那么直接反轉這2個元素使該子集成為減序即可得到pn+1。理由是pn和pn+1的前面m-2個元素都相等(沒有對前面的元素進行操作),僅能靠最后2個元素來分出大小。而這2個元素只能出現2種排列,其中較大的一種是減序。

  若pn的最后最多有s個元素構成一個減序子集,令i = m - s,則有pn(i) < pn(i+1),因此若將pn(i)和pn(i+1)調換必能得到一個較大的排列(不一定是下一個),因此必須保持pn(i)之前的元素不動,并在子集{pn(i+1), pn(i+2), ..., pn(m)}中找到一個僅比pn(i)大的元素pn(j),將二者調換位置。此時只要得到新子集{pn(i+1), pn(i+2), ..., pn(i), ...,pn(m)}的最小排列即可。注意到新子集仍保持減序,那么直接將其反轉即可得到最小的增序子集。

  按以上步驟便可從pn得到pn+1了。

  復雜度

  最好的情況為pn的最后的2個元素構成一個最小的增序子集,交換次數為1,復雜度為O(1),最差的情況為1個元素最小,而后面的所有元素構成減序子集,這樣需要先將第1個元素換到最后,然后反轉后面的所有元素。交換次數為1+(n-1)/2,復雜度為O(n)。這樣平均復雜度即為O(n/2)。

//STL的生成方法
bool my_next_permutation(int * const begin, int * const end)
{
    int *p1 , *p2;
    for(p1 = end - 1; p1!= begin; p1--)//找到序列中從后往前第一個元素1小于元素2的一對
    {
        if(*(p1-1)< *(p1))
            break;
    }
    if(p1==begin)//這種情況下序列已經完全逆序
        return false;
    p1--;//使p1指向小的那個數
    for(p2 = p1 + 1; p2 != end; p2++)//尋找p1后面比p1小但是最大的那個數
    //,這里利用了后面序列降序的性質
    {
        if(*p2 < *p1)
            break;
    }
    p2--;//p2指向后面比p1大但是最小的那個
    iter_swap(p1,p2);//交換p1,p2指向的元素
    reverse(p1+1,end);//注意是到end 反向而非p2
    return true;
}
 

請這樣調用

view plaincopy to clipboardprint?
do 
{  
    for(int i = 0; i < MAX; i++)  
    {  
        cout << d[i] << " ";  
    }  
    cout << endl;  
}while(my_next_permutation(d,d+MAX)); 
    do
    {
        for(int i = 0; i < MAX; i++)
        {
            cout << d[i] << " ";
        }
        cout << endl;
    }while(my_next_permutation(d,d+MAX));


部分內容引用:http://blog.csdn.net/heartnheart/archive/2010/10/20/5953150.aspx
posted on 2011-03-08 11:29 Cunch 閱讀(632) 評論(0)  編輯 收藏 引用 所屬分類: Algorithm
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲国产导航| 欧美二区不卡| 欧美二区视频| 免费成人性网站| 欧美大片18| 亚洲人成毛片在线播放| 麻豆九一精品爱看视频在线观看免费| 久久电影一区| 美国十次了思思久久精品导航| 老司机一区二区三区| 久久青青草综合| 欧美国产精品一区| 日韩一区二区精品葵司在线| aa国产精品| 欧美一级久久久久久久大片| 久久精品最新地址| 欧美精彩视频一区二区三区| 国产精品第三页| 在线成人激情黄色| 亚洲一区二区在线观看视频| 久久久久久久成人| 亚洲破处大片| 欧美一区二区在线观看| 免费不卡视频| 国产精品一区二区欧美| 在线播放亚洲| 午夜精品亚洲| 亚洲精品国产精品国自产在线| 亚洲综合二区| 欧美伦理91| 在线成人av.com| 校园激情久久| 99精品国产在热久久下载| 欧美专区在线观看一区| 欧美精品在线免费观看| 激情五月婷婷综合| 午夜精品一区二区三区四区| 欧美国产一区二区三区激情无套| 在线中文字幕一区| 久久精品成人一区二区三区| 亚洲欧洲精品天堂一级| 欧美在线观看一区二区三区| 欧美日韩无遮挡| 亚洲欧洲一区二区三区在线观看| 欧美一级午夜免费电影| 亚洲激情啪啪| 麻豆成人在线播放| 狠狠色狠狠色综合| 久久精品二区亚洲w码| 正在播放亚洲一区| 欧美男人的天堂| 亚洲黄色尤物视频| 欧美成人精品1314www| 欧美一区二区三区免费观看| 国产精品久久久久毛片大屁完整版| 亚洲茄子视频| 亚洲高清不卡在线| 欧美国产一区二区三区激情无套| 在线观看视频一区| 欧美成人午夜激情| 免费毛片一区二区三区久久久| 一区二区三区在线观看视频| 久久久青草青青国产亚洲免观| 亚洲一区免费看| 国产乱码精品一区二区三区忘忧草 | 最新亚洲一区| 亚洲激情一区二区| 欧美另类人妖| 午夜精品一区二区在线观看 | 欧美丝袜一区二区| 亚洲免费中文字幕| 午夜精品视频在线| 国产主播在线一区| 欧美成年视频| 欧美伦理影院| 欧美在线亚洲综合一区| 久久精品国产99精品国产亚洲性色| 国产欧美精品日韩精品| 久久精品道一区二区三区| 久久精品国产视频| 亚洲精品看片| 亚洲一区二区三区激情| 韩国精品在线观看| 亚洲片在线观看| 国产精品久久久一区二区三区 | 9i看片成人免费高清| 国产精品99一区二区| 久久国产精品高清| 欧美成人在线网站| 香蕉尹人综合在线观看| 久久久久久久波多野高潮日日| 亚洲欧洲一区二区天堂久久| 夜久久久久久| 在线观看一区欧美| 亚洲欧美激情视频在线观看一区二区三区 | 亚洲视频一区二区| 国产一区二区三区久久精品| 欧美成人午夜77777| 欧美日韩另类丝袜其他| 久久青青草综合| 国产精品jvid在线观看蜜臀| 久久深夜福利| 国产精品热久久久久夜色精品三区| 久久天天躁狠狠躁夜夜爽蜜月| 欧美激情在线有限公司| 久久精品亚洲精品| 欧美小视频在线| 亚洲国产成人av| 国产综合久久久久影院| 一区二区三区四区蜜桃| 亚洲激情视频| 久久久久国产一区二区三区四区 | 午夜精品在线观看| 欧美成人午夜影院| 久久综合色播五月| 国产精品人人做人人爽| 亚洲精品永久免费精品| 亚洲电影第1页| 久久精品一区二区国产| 欧美一级黄色网| 欧美日韩综合视频网址| 亚洲第一成人在线| 亚洲第一中文字幕| 老司机aⅴ在线精品导航| 久久久噜噜噜久久人人看| 国产精品视频免费在线观看| 日韩视频三区| 亚洲天堂成人在线观看| 欧美顶级大胆免费视频| 欧美成人首页| 亚洲黄一区二区三区| 久久久精彩视频| 麻豆成人综合网| 亚洲电影网站| 欧美成人免费全部观看天天性色| 欧美福利一区二区| 亚洲欧洲在线看| 欧美激情精品久久久六区热门 | 亚洲午夜激情网站| 欧美日韩国产一区二区| 亚洲精品久久久久久下一站 | 老色鬼久久亚洲一区二区| 国产日本亚洲高清| 欧美一区二区三区免费看| 久久精品视频在线观看| 狠狠色丁香久久婷婷综合丁香| 久久精品国产亚洲5555| 免费看的黄色欧美网站| 欧美精品91| 亚洲国产欧美不卡在线观看| 亚洲三级毛片| 欧美午夜不卡影院在线观看完整版免费| 亚洲破处大片| 亚洲免费影视第一页| 国产视频一区二区在线观看| 久久激情视频免费观看| 亚洲国产高清aⅴ视频| 亚洲视频观看| 国内精品久久久久影院 日本资源| 久久久噜噜噜久久中文字免| 亚洲国产成人久久综合一区| 一区二区三区产品免费精品久久75| 欧美日韩高清在线观看| 亚洲欧美激情四射在线日| 免费欧美视频| 亚洲男人的天堂在线观看| 狠狠久久婷婷| 欧美四级在线观看| 久久久五月婷婷| 一区二区三区 在线观看视频| 久久精品一区中文字幕| 日韩午夜在线电影| 国产一区二区成人| 欧美日韩99| 久久一二三国产| 亚洲午夜精品久久久久久app| 麻豆久久精品| 欧美一级视频精品观看| 亚洲精品一区二区三区四区高清| 国产精品一级| 欧美日韩三级| 免费观看成人| 久久精品五月| 亚洲欧美一区二区精品久久久| 亚洲国产cao| 快she精品国产999| 欧美一区二区国产| 亚洲素人一区二区| 亚洲精品久久久久久久久久久久久 | 欧美成人日本| 欧美在线视屏| 亚洲欧美日韩久久精品| 亚洲精品麻豆| 在线观看欧美视频| 国模私拍一区二区三区| 国产精品久久影院| 欧美三级视频在线| 欧美日韩dvd在线观看| 女女同性精品视频| 久久久久久高潮国产精品视|