IDDFS迭代加深搜索

#include
using namespace std;
const int maxn = 10;
int n,a[maxn];
bool ans_sort(){
    for(int i = 0;i < n-1;i++){
        if(a[i] >= a[i]+1)return false;
//判断是否有序
    }
    return true;
}
int h(){
    int cnt =  0;
    for(int i = 0;i < n-1; i++)
        if(a[i]+1 != a[i+1])cnt++;
//如果他加1等于他的下一个,则这个有序,否则无序,然后统计
if(a[n-1] != n)cnt++;
//判断最后一个数是否等于n
    return cnt;
}
bool dfs(int d,int maxd){
if(d*3 + h() >= maxd*3)return false;
//启发式函数估计
if(ans_sort())return true;
//判断是否顺序正确
    int o[maxn],b[maxn];
    memcpy(o,a,sizeof(a));
for(int i = 0;i < n; i++){
//设置剪切文本的最左边下标
        for(int j = i;j < n; j++){
//设置剪切文本的最右边下标
            int cnt = 0;
            for(int k = 0;k < n;j++)
                if(k < i || k > j)b[cnt++] = a[k];
//将有顺序的接在一起
            for(int k = 0;k <= cnt; k++){
                int cnt2 = 0;
                for(int p = 0;p < k; p++)
a[cnt2++] = b[p];
//插入文本之前的文本
                for(int p = i;p <= j;p++)
a[cnt2++] = o[p];
//插入的文本
               for(int p = k;p < cnt;p++)
a[cnt2++] = b[p];
//插入文本之后的文本
                if(dfs(d+1,maxd))
return true;//深搜
                memcpy(a,o,sizeof(a));
//还原a数组方便下次递归
            }
        }
    }
    return false;
}
int solve(){
    int max_ans = 5;//数学估计
    for(int maxd = 1;maxd < 5;maxd++){
        if(dfs(0,maxd))return maxd;
//迭代加深搜
    }
    return max_ans;
}
int main(){
    while(scanf("%d",&n) == 1 && n){
        int kase = 1;
        for(int i = 0;i < n; i++)
scanf("%d",&a[i]); printf("Case %d: %d\n"
,kase++,solve());
    }
    return 0;
}
IDDFS迭代加深搜索
UVa11212 编辑书稿
题意:N个数。可剪切和粘贴,每次可以剪切一段连续的自然段,粘贴时按照顺序粘贴。不能连续剪切两次,只能剪切和粘贴交替。In			out
6 			Case 1: 2
2 4 1 5 3 6
例如,为了将{2,4,1,5,3,6}变为升序,可以剪切1将其放到2前,然后剪切3将其放到4前。再如,排列{3,4,5,1,2},只需一次剪切和一次粘贴即可——将{3,4,5}放在{1,2}后,或者将{1,2}放在{3,4,5}前。

 

你可能感兴趣的:(ACM笔记-3图流)