Editing a Book UVA

来源:互联网 发布:三星网络摄像机密码 编辑:程序博客网 时间:2024/06/10 21:56

    You have n equal-length paragraphs numbered 1 to n. Now you want to arrange them in the orderof 1, 2, . . . , n. With the help of a clipboard, you can easily do this: Ctrl-X (cut) and Ctrl-V (paste)several times. You cannot cut twice before pasting, but you can cut several contiguous paragraphs atthe same time - they’ll be pasted in order.

    For example, in order to make {2, 4, 1, 5, 3, 6}, you can cut 1 and paste before 2, then cut 3 andpaste before 4. As another example, one copy and paste is enough for {3, 4, 5, 1, 2}. There are twoways to do so: cut {3, 4, 5} and paste after {1, 2}, or cut {1, 2} and paste before {3, 4, 5}.

Input

    The input consists of at most 20 test cases. Each case begins with a line containing a single integer n(1 < n < 10), thenumber of paragraphs. The next line contains a permutation of 1, 2, 3, . . . , n. Thelast case is followed by a single zero, which should not be processed.

Ouput

    For each test case, print the case number and the minimal number of cut/paste operations.

枚举区间,用IDA*算法剪枝即可。

第一次写这题的时候,总感觉是有什么数学方法能直接解决,想不到了就只有dfs暴力了咯,第一次写时弄错启发函数了,直接超时,参考了刘老师的启发函数才过掉。

中间其实有个技巧,粘贴复制的过程其实相当于两个相邻子区间的互换。互换只要从前往后换即可,因为向前与向后是整体对称的。

还有一点需要强调,bool类型函数默认返回true值而不是false值,我已经两次搞错了,心累啊T_T

AC代码(0ms)

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<iostream>#include<cstdlib>#include<stack>#include<set>#include<map>#include<vector>#include<queue>#include<sstream>#include<utility>#include<ctype.h>using namespace std;typedef pair<int,int> Pair;/* G++ 5.1.0 */int num[10], a[10];int maxn, n;int h() {int cnt = 0;for(int i=0; i<n-1; i++)if(a[i]+1 != a[i+1]) cnt ++;if(a[n-1] != n) cnt ++;return cnt;}bool dfs(int beg) {if(beg == maxn) {if(h()==0) return true;return false;}if(3*beg + h() > 3*maxn) return false;int olda[10], suba[10], subb[10];memcpy(olda, a, sizeof(a));for(int i=0; i<n; i++)for(int j=i; j<n; j++) {int  cnt1 = 0;for(int k=i; k<=j; k++) suba[cnt1++] = olda[k];for(int k=j+1; k<n; k++) {int cnt2 = 0;for(int t=j+1; t<=k; t++) subb[cnt2++] = olda[t];int c1 = 0, c2 = 0;for(int t=0; t<n; t++) { if(t<i) a[t] = olda[t]; else if(t<i+cnt2) a[t] = subb[c1++]; else if(t<i+cnt2+cnt1) a[t] = suba[c2++]; else a[t] = olda[t];}if(dfs(beg+1)){return true;}}}return false;}int main() {int kase = 0;while(scanf("%d", &n) && n) {maxn = 0;int na[10];for(int i=0; i<n; i++) scanf("%d", &na[i]);memcpy(a, na, sizeof(na));printf("Case %d: ", ++kase);if(h()==0) printf("0\n"); else{for(maxn=1; maxn<5; maxn++) {memcpy(a, na, sizeof(na));if(dfs(0)) break;} }if(maxn) {printf("%d\n", maxn);}}}


0 0
原创粉丝点击