• noip模拟赛(10.4) 序列(sequence)


    序列(sequence)

    【题目描述】

    给定一个1~n的排列x,每次你可以将x1~xi翻转。你需要求出将序列变为升序的最小操作次数。有多组数据。

    【输入数据】

    第一行一个整数t表示数据组数。

    每组数据第一行一个整数n,第二行n个整数x1~xn。

    【输出数据】

          每组数据输出一行一个整数表示答案。

    【样例输入】

    1

    8

    8 6 1 3 2 4 5 7

    【样例输出】

    7

    【数据范围】

    对于100%的测试数据,t=5,n<=25。

    对于测试点1,2,n=5。

    对于测试点3,4,n=6。

    对于测试点5,6,n=7。

    对于测试点7,8,9,n=8。

    对于测试点10,n=9。

    对于测试点11,n=10。

    对于测试点i (12<=i<=25),n=i。

    【题解】

    正解:启发式搜素+迭代

    即,在暴力的迭代搜索基础上,加上估价函数。

    估价函数的映射规则是这样的:因为每次翻转后区间内相邻的数字出现了变化 的都是1和第i个数,当第i个数与相邻的后一个数之间差值正好为1时,这次交换导致求解的期望次数一定会+1,由此得到当目前的步数+期望步数>迭代限制时,剪枝。

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    using namespace std;
    const int N=50;
    inline int read()
    {
    	int x=0,c=getchar(),f=1;
    	while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
    	while(c>47&&c<58)x=x*10+c-48,c=getchar();
    	return x*f;
    }
    bool flag;
    int n,a[N],m;
    inline void rev(int i)
    {
    	for(int j=1;j<=(i>>1);j++)
    		swap(a[j],a[i-j+1]);
    }
    inline void dfs(int i,int k)
    {
    	int j,l;
    	if(i+k>m)return;
    	for(j=1;j<=n;j++)
    		if(a[j]^j)
    			break;
    	if(j>n){
    		flag=1;
    		return;
    	}
    	for(j=2;j<=n;j++){
    		l=k+(j<n && abs(a[j]-a[j+1])==1)-(j<n && abs(a[1]-a[j+1])==1);
    		rev(j);
    		dfs(i+1,l);
    		rev(j);
    		if(flag)
    			return;
    	}
    }
    int main()
    {
    	freopen("sequence.in","r",stdin);
    	freopen("sequence.out","w",stdout);
    	int i,k,T=read();
    	while(T--){
    		n=read();
    		for(i=1;i<=n;i++)
    			a[i]=read();
    		for(i=1,k=0;i<=n-1;i++)
    			if(abs(a[i]-a[i+1])>1)
    				k++;
    		for(m=0;;m++){
    			flag=0;
    			dfs(0,k);
    			if(flag)
    				break;
    		}
    		printf("%d
    ",m);
    	}
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }



  • 相关阅读:
    bash命令
    集群解析
    临时配置网络(ip,网关,dns)+永久配置
    nginx反向代理三台web
    源码安装nginx
    nginx反向代理+三台web+nfs共享存储实现集群配置
    jQuery学习笔记(一):入门【转】
    你是怎么把字符串“2016-11-16” 变为 “16/11/2016” 的? 【转】
    用css画出三角形【转】
    JS中常遇到的浏览器兼容问题和解决方法【转】
  • 原文地址:https://www.cnblogs.com/keshuqi/p/5957687.html
Copyright © 2020-2023  润新知