紫书搜索 例题7-10 UVA

来源:互联网 发布:乐乎亚洲雄风的喜欢 编辑:程序博客网 时间:2024/03/28 18:00

题目链接:

https://vjudge.net/problem/UVA-11212

题意:

题解:

IDA*,每次改变深度上限去剪枝

代码:

#include <bits/stdc++.h>using namespace std;typedef long long ll;#define MS(a) memset(a,0,sizeof(a))#define MP make_pair#define PB push_backconst int INF = 0x3f3f3f3f;const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;inline ll read(){    ll x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}//////////////////////////////////////////////////////////////////////////const int maxn = 1e5+10;int n;int a[15];bool is_sort(){    for(int i=1; i<=n; i++)        if(a[i] != i) return false;    return true;}int h(){  // 估值函数,有几个位置不正确,就是 不连续的位置    int cnt = 0;     for(int i=1; i<n; i++)         if(a[i]+1 != a[i+1]) cnt++;     if(a[n] != n) cnt++;    return cnt;}bool dfs(int cur,int maxd){    if((maxd-cur)*3 < h()) return false;  // 剪枝, 每剪切一次,最多使三个位置正确    if(is_sort()) return true;    int b[15],olda[15];    memcpy(olda,a,sizeof(a));    for(int i=1; i<=n; i++)        for(int j=i; j<=n; j++){ // 枚举剪切位置            int cnt=1;            for(int k=1; k<=n; k++){                if(k<i || k>j) b[cnt++] = a[k];  // 没有剪掉的数字            }            for(int p=1; p<=cnt; p++){ // 枚举放在哪个位置                int cnt2 = 1;                for(int k=1; k<p; k++) a[cnt2++] = b[k];                for(int k=i; k<=j; k++) a[cnt2++] = olda[k];                 for(int k=p; k<cnt; k++) a[cnt2++] = b[k];                if(dfs(cur+1,maxd)) return true;                memcpy(a,olda,sizeof(olda));            }        }    return false;}int solve(){    int maxd;    if(is_sort()) return 0;    for(maxd=1; maxd<=8; maxd++){ // 最多9个数字,最大也就移动8次        if(dfs(0,maxd)) return maxd;    }}int main(){    int cas = 0;    while(scanf("%d",&n) && n){        for(int i=1; i<=n; i++)            a[i] = read();        printf("Case %d: %d\n",++cas,solve());    }    return 0;}
0 0
原创粉丝点击