您的位置:首页 > 其它

uva11212 编辑书稿 迭代加深

2016-08-05 00:44 375 查看
迭代加深,逐层计算。

乐观估价函数,剪枝。

递归枚举,利用数组保存数据,之后恢复。

剪切一个片段并粘贴,最多改变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 <iostream>
#include <cstdio>
#include <cstring>

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\n", ++kase, solve());
}
return 0;
}


在林伏案的博客上加了一些修改,代码来自http://blog.csdn.net/qq_29169749/article/details/51419907
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva11212 迭代加深