zoukankan      html  css  js  c++  java
  • BZOJ 2824: [AHOI2012]铁盘整理

    BZOJ 2824: [AHOI2012]铁盘整理

    标签(空格分隔): OI-BZOJ OI-搜索


    Time Limit: 10 Sec
    Memory Limit: 128 MB


    Description

    在训练中,一些臂力训练器材是少不了的,小龙在练习的时候发现举重器械上的铁盘放置的非常混乱,并没有按照从轻到重的顺序摆放,这样非常不利于循序渐进的锻炼。他打算利用一个非常省力气的办法来整理这些铁盘,即每次都拿起最上面的若干个圆盘并利用器械的力量上下翻转,这样翻转若干次以后,铁盘将会按照从小到大的顺序排列好。那么你能不能帮小龙确定,最少翻转几次就可以使铁盘按从小到大排序呢?
    例如:下面的铁盘经过如图2.1所示的以下几个步骤的翻转后变为从小到大排列。
    此处输入图片的描述

    Input

    共两行,第一行为铁盘个数N(1≤N≤50)。第二行为N个不同的正整数(中间用空格分开),分别为从上到下的铁盘的半径 R(1≤R≤100)
    Output

    一个正整数,表示使铁盘按从小到大有序需要的最少翻转次数。

    Sample Input

    5

    2 4 3 5 1

    Sample Output

    5


    Solution####

    搜索,剪枝方法:可以发现每次翻转只会改变一对相邻的铁盘,那么翻转为有序至少需要翻转【不应该相邻的铁盘数】次。


    Code####

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    #include<bitset>
    #include<vector>
    using namespace std;
    #define PA pair<int,int>
    int read()
    {
     	int s=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+ch-'0';ch=getchar();}
    	return s*f;
    }
    //smile please
    int n,a[51];
    int ls[105],ans,sum,pr;
    void dfs()
    {
    	if(sum+pr>=ans)return;
    	if(pr==0&&a[1]==1)
    	  {ans=sum;return;}
    	for(int i=2;i<=n;i++)
    	   {
    	   	if(i!=n)pr+=(abs(a[1]-a[i+1])!=1)-(abs(a[i]-a[i+1])!=1);
    	   	for(int j=1;j<i+1-j;j++)
    	   	    swap(a[j],a[i-j+1]);
    	   	++sum;
    		dfs();
    	   	--sum;
    	   	for(int j=1;j<i+1-j;j++)
    	   	    swap(a[j],a[i-j+1]);
    	   	if(i!=n)pr-=(abs(a[1]-a[i+1])!=1)-(abs(a[i]-a[i+1])!=1);
    	   }
    }
    int main()
    {
     	//freopen(".in","r",stdin);
    	//freopen(".out","w",stdout);
    	n=read();
    	for(int i=1;i<=n;i++)a[i]=read(),ls[a[i]]++;
    	for(int i=1;i<=100;i++)ls[i]+=ls[i-1];
    	for(int i=1;i<=n;i++)a[i]=(ls[a[i]]--);
    	ans=n*2-2;
    	for(int i=1;i<n;i++)
    	    if(abs(a[i+1]-a[i])!=1)
    	       pr++;
    	dfs();
    	printf("%d
    ",ans);
    	//fclose(stdin);
    	//fclose(stdout);
    	return 0;
    }
    
    
  • 相关阅读:
    jQuery核心函数——(一)
    ECMAScript——(二)
    JS简介——(一)
    jQuery动态给下拉列表添加一个选项(创建DOM对象)
    Ajax异步请求struts的JSON机制(省市区三级联动)
    struts2官方演示程序总结struts2-blank
    详解数据库之存储过程与错误处理
    使用jdk的socket通信
    hadoop深入研究:(五)——Archives
    解决删除Volume报错的问题
  • 原文地址:https://www.cnblogs.com/wuyuhan/p/5295523.html
Copyright © 2011-2022 走看看