您的位置:首页 > 其它

[IDA*] UVa11212 Editing a Book 普通的IDA* 1

2018-03-28 23:21 507 查看

题目

VJUDGE

代码

#include "stdafx.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>

const int maxn = 10;
int a[10], n;

bool finaled() {
for (int i = 0; i < n - 1; i++)
if (a[i] + 1 != a[i + 1]) return false;
return true;
}

int h() {
int ans = 0;
for (int i = 0; i < n - 1; i++)
if (a[i]+1 != a[i + 1]) ans++;   // why not a[i]+1 != a[i+1]
if (a[n - 1] != n) ans++; ////////////////
return ans;
}

bool dfs(int d, int maxd) {
//for (int i = 0; i < n; i++) printf("%d ", a[i]);
//printf("%d --->>> %d\n", d, maxd);
if (finaled()) return true;
if (d * 3 + h() > maxd * 3) return false;

int olda[maxn], b[maxn];
memcpy(olda, 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; k++)
if (k<i || k>j) b[cnt++] = olda[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++] = olda[p];
for (int p = k; p < cnt; p++) a[cnt2++] = b[p];
if (dfs(d + 1, maxd)) return true;
memcpy(a, olda, sizeof(a)); //////////////////
}
}

return false;
}

int main() {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int kase = 0;
while (scanf("%d", &n) == 1 && n) {
for (int i = 0; i < n; i++) scanf("%d", &a[i]);
if (finaled()) {
printf("Case %d: 0\n", ++kase);
continue;
}
int maxd;
for (maxd = 1; maxd < 5; maxd++) {
if (dfs(0, maxd)) break;
else if (maxd == 4) {
maxd = 5;
break;
}           /////////////////
}
printf("Case %d: %d\n", ++kase, maxd);
}
//system("PAUSE");
return 0;
}


体会

IDA*,先摆出剪枝条件:

d+h()>maxdd+h()>maxd
h()=a[i]+1!=a[i+1]的数目3h()=a[i]+1!=a[i+1]的数目3

此处的h()是值得关注的,首先除以3好理解,因为一次剪切粘贴,最多会使3个数字的后置数字发生改变,因此还要执行的操作数就是后置数字不正确的数字的个数除以3。

而这里使用了“后置数字不正确”这个概念,而可以发现,LRJ的代码通篇都是围绕着这个概念的。一般我们想这种问题,都是会想的a[i] != i这样。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  搜索 IDA*