zoukankan      html  css  js  c++  java
  • Face The Right Way 开关(POJ3276)

    描述:
    ( N 头牛排成了一列。每头牛或者向前或者向后。为了让所有的牛都面向前方,农夫约翰买了 一台自动转向的机器。 这个机器在购买时就必须设定一个数值 K,机器每操作一次恰好使 K 头连续的牛转向。 请求出为了让所有的牛都能面向前方需要的最少的操作次数 M 和对应的 最小的 K。 前是'F',后是'B')

    枚举一个K,然后考虑如何求出此时的M.

    一、如果第一头牛需要反转,因为只有1-K这个区间包含它,所以一定要翻转

    二、考虑第二头牛,如果需要翻转那么重复上面的步骤。

    这样的复杂度是(O(n^3))

    每次翻转牛,需要把k头牛都去翻转,这太麻烦了,可以优化掉。

    (f[i])表示以i为起点的区间是否翻转过

    那么如果f[i]=1,它的效果一直持续到f[i+k]就失效了

    所以维护一个sumn变量,表示在i以前k-1头牛翻转过的次数

    那么每次循环,要sumn-=f[i-k+1],因为已经失效

    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int n,f[5009];//f[i]表示i,i+1,.....i+k-1牛都反转
    char cow[5009];
    int fun(int k)
    {
    	memset(f,0,sizeof(f));
    	int ans=0;//反转次数
    	int sumn=0;
    	for(int i=1;i<=n-k+1;i++)
    	{
    		if(sumn%2==0&&cow[i]=='B')//要反转了 
    			f[i]=1,ans++;
    		else if(sumn%2==1&&cow[i]=='F')//要反转了
    			f[i]=1,ans++;
    		sumn+=f[i];
    		if(i-k+1>=1)	sumn-=f[i-k+1];
    	} 
    	//第n-k+2头牛以后不能反转了,判断是否可行
    	for(int i=n-k+2;i<=n;i++)
    	{
    		if(sumn%2==0&&cow[i]=='B')	return -1;
    		else if(sumn%2==1&&cow[i]=='F')	return -1;
    		sumn+=f[i];
    		if(i-k+1>=1)	sumn-=f[i-k+1];
    	}
    	return ans; 
    } 
    int main()
    {
    	cin>>n;
    	for(int i=1;i<=n;i++)	cin>>cow[i];
    	int k,ans=999999999;
    	for(int i=1;i<=n;i++)//判断步长i时是否可行 
    	{
    		int x=fun(i);
    		if(x!=-1&&x<ans)
    		k=i,ans=x;
    	}
    	cout<<k<<" "<<ans;
    }
    
  • 相关阅读:
    VisualVM工具的使用
    jstack的使用
    JVM内存溢出的定位与分析
    初识JVM
    JVM运行参数
    VIM 常用命令
    python3 简单抓取图片2
    python3 抓取图片
    node.js GET 请求简单案例
    node.js 爬虫
  • 原文地址:https://www.cnblogs.com/iss-ue/p/12605645.html
Copyright © 2011-2022 走看看