标签:log 5.6 链接 min process 入门 tin mos space
/** 题目:Editing a Book UVA - 11212 链接:https://vjudge.net/problem/UVA-11212 题意:lrjP208. 思路:启发函数:当前已经操作的步数d,限制的步数maxd,后继不相同的个数x。 由于每一步最多使x减少3,所以如果3*d+x>maxd*3;那么肯定不行。 如果通过位置不同的个数作为启发,是不行的,无法判断。 如果是每个数的后继不同的数有多少个。那么可以推算出每一步操作后,最多减少3个不同的后继。 最终结果所有后继都满足。即a[i] = a[i-1]+1; 具体看lrj算法竞赛入门经典P209; */ #include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef long long LL; const int mod=1e9+7; const int maxn=1e2+5; const double eps = 1e-12; int a[10], n; int getDif()///获得后继不合法数. { int cnt = 0; for(int i = 2; i <= n; i++){ if(a[i]!=a[i-1]+1){ cnt++; } } return cnt; } int temp[10]; void Move(int *temp,int *a,int L,int R,int LL,int RR) { int now = L; for(int i = LL; i <= RR; i++){ a[now++] = temp[i]; } for(int i = L; i <= R; i++){ a[now++] = temp[i]; } } bool dfs(int d,int maxd) { if(3*d+getDif()>3*maxd) return false; if(getDif()==0) return true; int odd[10]; memcpy(odd,a,sizeof(int)*(n+1)); ///如果[L,R]是连续的,那么不需要剪切。 for(int i = 1; i <= n; i++){ for(int j = i; j <= n; j++){ for(int k = j+1; k <= n; k++){///每次交换[i,j],[j+1,k];每次交换相邻的两段区间。 Move(odd,a,i,j,j+1,k); if(dfs(d+1,maxd)) return true; memcpy(a,odd,sizeof(int)*(n+1));///保证每一次操作后,把a复原。 } } } return false; } int main() { int cas = 1; while(scanf("%d",&n)==1) { if(n==0) break; for(int i = 1; i <= n; i++) scanf("%d",&a[i]); for(int maxd = 0; ; maxd++){ if(dfs(0, maxd)){ printf("Case %d: %d\n",cas++,maxd); break; } } } return 0; }
Editing a Book UVA - 11212 IDA*
标签:log 5.6 链接 min process 入门 tin mos space
原文地址:http://www.cnblogs.com/xiaochaoqun/p/6899606.html