码迷,mamicode.com
首页 > 其他好文 > 详细

[2016-02-27][UVA][11212][Editing a Book]

时间:2016-02-27 16:25:28      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:

[2016-02-27][UVA][11212][Editing a Book]


  • 时间:2016-02-26 19:38:44 星期五
  • 题目编号:UVA 11212
  • 题目大意:给定长度为n(值为1~n)的序列,求把该序列 复制/粘贴 成1~n 的排列最少步数
  • 分析:
    • 状态空间搜索,但是每次状态转移的方式有多种,可能会T,
    • 发现,最多 操作 的次数:n~1的序列,每次操作 长度为1的连续段,那么需要 n-1 次操作
    • 可以用IDA*算法
    • 剪枝,每次操作之后,每个数字的后继数字不正确的数目h,最多减少3,
    • 那么至少需要 h / 3 次操作才能,达到目标
  • 方法:IDA*
    • 数据是10个长度,所以,结贴操作直接for语句完成      
    • dfs过程,层数达到maxd,判断是否排列好
    • 如果预测最少层数大于maxd,直接返回
    • dfs ,枚举起点和宽度,截取这一段数字,放在起点前面任意一个点,然后进入下层dfs


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
typedef long long LL;
#define CLR(x,y) memset((x),(y),sizeof((x)))
#define FOR(x,y,z) for(int (x)=(y);(x)<(z);++(x))
#define FORD(x,y,z) for(int (x)=(y);(x)>=(z);--(x))
#define FOR2(x,y,z) for((x)=(y);(x)<(z);++(x))
#define FORD2(x,y,z) for((x)=(y);(x)>=(z);--(x))
const int maxn = 11;
int x[maxn],n,a[maxn];
int is_sorted(){
        FOR(i,0,n)
                if(a[i] != i + 1)       return 0;
        return 1;
}
int h(){
        int cnt = 0;
        FOR(i,0,n - 1){
                if(a[i] + 1 != a[i + 1])
                        ++cnt;
        }
        return cnt;
}
int dfs(int curcnt,int & maxd){
        //成功返回1,同时结束bfs
        if(curcnt == maxd)      return is_sorted();
        //超过范围
        if(curcnt*3 + h() > 3 * maxd)   return 0;
        int tmp[maxn];
        memcpy(tmp,a,sizeof(int)*n);
        FOR(i,1,n){//枚举长度
                for(int j = 0; i + j - 1 < n;++j){//枚举起点
                        //剪切 区段
                        int t1[maxn],t2[maxn],c1 = -1,c2 = -1;
                        FOR(k,0,n){
                             if( k >= j && k < i + j)  t1[++c1] = tmp[k];
                             else t2[++c2] = tmp[k];
                        }
                        //粘贴区段
                        FOR(k,0,j){
                                int c = -1;
                                FOR(l,0,k)      a[++c] = t2[l];
                                FOR(l,0,c1+1)     a[++c] = t1[l];
                                FOR(l,k,c2+1)     a[++c] = t2[l];
                                //进入下层dfs
                                if(dfs(curcnt + 1,maxd))        return 1;
                        }
                }
        }
        return 0;
}
int main(){
        int cntcase = 0;
        while(~scanf("%d",&n) && n){
                FOR(i,0,n)      scanf("%d",x+i);
                int i;
                //枚举步骤数目,
                for(i = 0;;++i){
                        memcpy(a,x,sizeof(int)*n);
                        if(dfs(0,i))    break;
                }
                printf("Case %d: %d\n",++cntcase,i);
        }
    return 0;
}  






[2016-02-27][UVA][11212][Editing a Book]

标签:

原文地址:http://www.cnblogs.com/qhy285571052/p/5223048.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!