zoukankan      html  css  js  c++  java
  • [UVA] 11212 Editing a Book

    笔记

    S:问题的一种状态

    h*(S):所求的最短距离

    h(s):S的估价函数

    g(s):S之前的代价函数

    f(s):s的启发函数

    h(s)

    有h(s)<=h*(s)

    相容

    定义:如果h(s)对于任意状态S1,S2都有h(S1)<=h(s2)+C(s1,s2),C(s1,s2)指从状态S1到S2的代价,则有h(s)是相容的。
    也就是说,h(s)不能减小得太快。

    g(s)

    通常用搜索树的深度代表。

    f(s)

    作为s的启发函数,也就是到达目标的总代价,显然有f(s)=g(s)
    +h(s),即已付出的代价加上预估要付出的代价。
    ==h(s)相容时,f(s)单调递增。==

    证明
    h(S1)<=h(S2)+C(S1,S2)  
    h(s1)+g(s1)<=h(S2)+g(S1)+C(S1,S2) 
    显然有  
    h(s1)+g(s1)<=h(S2)+g(S2)f(s1)<=f(s2)
    You have n equal-length paragraphs numbered 1 to n. Now you want to arrange them in the order
    of 1, 2, . . . , n. With the help of a clipboard, you can easily do this: Ctrl-X (cut) and Ctrl-V (paste)
    several times. You cannot cut twice before pasting, but you can cut several contiguous paragraphs at
    the same time - they’ll be pasted in order.
    For example, in order to make {2, 4, 1, 5, 3, 6}, you can cut 1 and paste before 2, then cut 3 and
    paste before 4. As another example, one copy and paste is enough for {3, 4, 5, 1, 2}. There are two
    ways to do so: cut {3, 4, 5} and paste after {1, 2}, or cut {1, 2} and paste before {3, 4, 5}.
    Input
    The input consists of at most 20 test cases. Each case begins with a line containing a single integer n
    (1 < n < 10), thenumber of paragraphs. The next line contains a permutation of 1, 2, 3, . . . , n. The
    last case is followed by a single zero, which should not be processed.
    Output
    For each test case, print the case number and the minimal number of cut/paste operations.
    Sample Input
    6
    2 4 1 5 3 6
    5
    3 4 5 1 2
    0
    Sample Output
    Case 1: 2
    Case 2: 1

    h()函数设计为段落中错位的段数,每次剪贴有可能改变3,不相容..
    所以取h()/3作为新的h(),把f,g,h,mxdp都同时扩大三倍。
    用DFS的好处就是不用排序(堆白学了的感觉)和判重,再加上迭代加深,比较浅的解可以很快地求出来。

    //Writer:GhostCai && His Yellow Duck
    
    #include<iostream>
    #include<cstring>
    using namespace std;
    
    int n;
    int a[20];
    
    bool check(){
        for(int i=1;i<n;i++) if(a[i+1]!=a[i]+1) return false;//
        return true;
    }
    
    int g(int dp){
        return dp*3;
    }
    
    int h(){
        int sum=0,i;
        for(i=1;i<n;i++){
            if(a[i+1]!=a[i]+1) sum++;//!!
        }
        return sum;
    }
    
    int f(int dp){
        return g(dp)+h();
    }
    
    bool dfs(int dp,int mxdp){
        if(f(dp)>3*mxdp) return false;// 
        if(check()) return true;
        int pre[20],cut[20],cnt;
        for(int i=1;i<=n;i++){
            for(int j=i;j<=n;j++){
                while(a[j+1]==a[j]+1) j++;//跳过排好的部分 
                memcpy(pre,a,sizeof(a));//保存当前状态
                cnt=0;
                for(int k=1;k<=n;k++){
                    if(k<i||k>j) cut[++cnt]=a[k];
                }
                for(int k=1;k<=cnt+1;k++){//+1 
                    int tcnt=0;
                    for(int t=1;t<k;t++) a[++tcnt]=cut[t];//!!!t<=k
                    for(int t=i;t<=j;t++) a[++tcnt]=pre[t];
                    for(int t=k;t<cnt;t++) a[++tcnt]=cut[t];
                    if(dfs(dp+1,mxdp)) return true;
                    memcpy(a,pre,sizeof(pre));//回溯 
                }
            }
        }
        return false;//!!!
    }
    
    int main(){
        int mycnt=1;
        bool flag=0;
        while(cin>>n){
            if(n==0) return 0;
            memset(a,0,sizeof(a));
            flag=0;
            for(int i=1;i<=n;i++) cin>>a[i];
            if(check()){
                 cout<<"Case "<<mycnt++<<":"<<0<<endl;
                continue;
            }
            for(int i=1;i<=8;i++){//迭代加深 限制深度
                if(flag) continue;
                if(dfs(0,i)){
                    cout<<"Case "<<mycnt++<<":"<<i<<endl;
                    flag=1;
                    continue;
                }
            }
        }
        return 0;
    }
    

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9247532.html

  • 相关阅读:
    JS、LUA都可以开发移动应用
    正在融资中的快速移动应用开发平台
    赶快加入快速移动应用开发吧
    重新诠释移动应用开发
    快速开发移动应用的利器
    报表实施案例:某市利用大数据助力精准扶贫项目开展
    【新手速成】菜鸟如何在三天内完成系统开发
    全新Wijmo5中文学习指南正式上线
    SpreadJS 在 Angular2 中支持绑定哪些属性?
    【报表福利大放送】100余套报表模板免费下
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9247532.html
Copyright © 2011-2022 走看看