uva 11212編集原稿の反復が深まります.


  • 反復は深まり、層単位で計算される.
  • 楽観評価関数、剪定.
  • は再帰的に列挙し、配列を利用してデータを保存し、その後回復する.
  • は1つのフラグメントを切り取り、貼り付けて、最大3つの拡張子を変更します.
  • 反復深化された基本的なフレームワーク.
  • テーマリンク:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=23956 フレーム:
    is_success()//    
    h()//    ,    
    dfs()//  
    {
        is_success();
        h();//  h()        
        for()//    
        {
                  。
                  。
                。//    memcpy()    
        }
    }
    solve()//        
    {
        if(is_success)//         。
        int max_ans;//     
        for(maxd = 0;;maxd++)
        {
            if(dfs(0,maxd))
                return maxd;
        }
        return max_ans;
    }
    この問題の標準コード:
    #include 
    #include 
    #include 
    
    using namespace std;
    const int maxn = 10;
    
    int n, book[maxn];
    
    bool is_goal() {//      
        bool ok = true;
        for(int i = 0; i < n; i++) {
            if(book[i] != i + 1) {
                ok = false;
                break;
            }
        }
        return ok;
    }
    
    int h() {//             
        int cnt = 0;
        for(int i = 0; i < n - 1; i++) {
            if(book[i] + 1 != book[i + 1])
                cnt++;
        }
        if(book[n - 1] != n)    cnt++;
        return cnt;
    }
    
    
    bool dfs(int d, int maxd) {
        if(3 * d + h() > maxd * 3)  return false;           //  ,                
        if(is_goal())               return true;
    
                                                            //            
        int old_book[maxn];                                 //       book     ,       book
        int past_to[maxn];                                  //         
        for(int i = 0; i < n; i++)
        for(int j = i; j < n; j++) {                        //          ,i     ,j     
            memcpy(old_book, book, sizeof(book));           //    book
    
            int cnt = 0;
            for(int k = 0; k < n; k++)
                if(k < i || k > j)
                    past_to[cnt++] = book[k];               //      
    
            for(int k = 0; k <= cnt; k++) {                 //        k    
                int cnt2 = 0;                               //      
                for(int p = 0; p < k; p++)      book[cnt2++] = past_to[p];
                for(int p = i; p <= j; p++)     book[cnt2++] = old_book[p];
                for(int p = k; p < cnt; p++)    book[cnt2++] = past_to[p];
    
                if(dfs(d + 1, maxd))    return true;        //    
                memcpy(book, old_book, sizeof(old_book));   //                    
            }//        ,        。
        }
        return false;
    }
    
    int solve() {//        
        if(is_goal())   return 0;
        for(int maxd = 0; maxd < 9; maxd++)                 //    ,     9 dfs      
            if(dfs(0, maxd))    return maxd;
        return -1;
    }
    
    int main()
    {
        //freopen("input.txt", "r", stdin);
        int kase = 0;
        while(~scanf("%d", &n) && n) {
            memset(book, 0, sizeof(book));
            for(int i = 0; i < n; i++)  scanf("%d", &book[i]);
            printf("Case %d: %d
    "
    , ++kase, solve()); } return 0; }
    林伏事件のブログにいくつかの修正を加えました.コードはhttp://blog.csdn.net/qq_29169749/articale/detail/51419907