zoukankan      html  css  js  c++  java
  • 奶牛排队的题解

    有 N 头牛排成一列,有的面朝前,有的面朝后。
    每次操作可以选择任意连续的 K 头牛,并改变它们的朝向。
    请求出最小的 K,使得将所有牛的朝向都变为朝前所需的操作次数最少。

    我们去枚举 kk,然后贪心去check

    复杂度 O(n3)O(n^3)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    template<typename T>inline void read(T &FF){
    	T RR=1;FF=0;char CH=getchar();
    	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
    	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
    	FF*=RR;
    }
    template<typename T>inline void write(T x){
    	if(x<0)putchar('-'),x*=-1;
    	if(x>9)write(x/10);
    	putchar(x%10+48);
    }
    template<typename T>inline void writen(T x){
    	write(x);
    	puts("");
    }
    int n,a[3010],ans=INT_MAX,xi,b[3010];
    queue<int>q;
    int work(int x){
    	for(int i=1;i<=n;i++)b[i]=a[i];
    	int s=0;
    	for(int i=1;i<=n;i++){
    		if(b[i]%2==1){
    			if(i+x-1>n)return INT_MAX;
                for(int i=1;i<k;i++)b[i+k]^=1;
    			s++;
    		}
    	}return s;
    }
    int main(){
    	read(n);
    	for(int i=1;i<=n;i++)read(a[i]);
    	for(int i=1;i<=n;i++){
    		int x=work(i);
    		if(x<ans){
    			xi=i;
    			ans=x;
    		}
    	}cout<<xi;
    	return 0;
    }
    

    这样就有90分了。

    100分做法有2种。都是去优化上述算法给后面数加的浪费时间的问题。

    • 可以差分
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    template<typename T>inline void read(T &FF){
    	T RR=1;FF=0;char CH=getchar();
    	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
    	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
    	FF*=RR;
    }
    template<typename T>inline void write(T x){
    	if(x<0)putchar('-'),x*=-1;
    	if(x>9)write(x/10);
    	putchar(x%10+48);
    }
    template<typename T>inline void writen(T x){
    	write(x);
    	puts("");
    }
    int n,a[3010],ans=INT_MAX,xi,b[3010];
    queue<int>q;
    int work(int x){
    	memset(b,0,sizeof(b));
    	int s=0;
    	for(int i=1;i<=n;i++){
    		b[i]+=b[i-1];
    		if((b[i]+a[i])%2==1){
    			if(i+x-1>n)return INT_MAX;
    			b[i]++;
                b[i+x]--;
    			s++;
    		}
    	}return s;
    }
    int main(){
    	read(n);
    	for(int i=1;i<=n;i++)read(a[i]);
    	for(int i=1;i<=n;i++){
    		int x=work(i);
    		if(x<ans){
    			xi=i;
    			ans=x;
    		}
    	}cout<<xi;
    	return 0;
    }
    
    • 可以用单调队列
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    template<typename T>inline void read(T &FF){
    	T RR=1;FF=0;char CH=getchar();
    	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
    	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
    	FF*=RR;
    }
    template<typename T>inline void write(T x){
    	if(x<0)putchar('-'),x*=-1;
    	if(x>9)write(x/10);
    	putchar(x%10+48);
    }
    template<typename T>inline void writen(T x){
    	write(x);
    	puts("");
    }
    int n,a[3010],ans=INT_MAX,xi,b[3010];
    queue<int>q;
    int work(int x){
    	while(q.size())q.pop();
    	int s=0;
    	for(int i=1;i<=n;i++){
    		while(q.size()&&i-q.front()>=x)q.pop();
    		if((a[i]+q.size())%2==1){
    			if(i+x-1>n)return INT_MAX;
    			s++,q.push(i);
    		}
    	}return s;
    }
    int main(){
    	read(n);
    	for(int i=1;i<=n;i++)read(a[i]);
    	for(int i=1;i<=n;i++){
    		int x=work(i);
    		if(x<ans){
    			xi=i;
    			ans=x;
    		}
    	}cout<<xi;
    	return 0;
    }
    
  • 相关阅读:
    实验5&期中考试后两题
    实验四——再探类
    实验3—初识类
    10.29算法训练——poj1475双重BFS
    10.25算法训练——裸线段树
    探索邻接表
    Hadoop学习之Combiner
    关于VLM模式下linux压缩根目录空间的心得
    C#微信公众号开发系列教程四(接收普通消息)
    c#分部类型详解
  • 原文地址:https://www.cnblogs.com/zhaohaikun/p/12816975.html
Copyright © 2011-2022 走看看