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;
    }
    
  • 相关阅读:
    【题解】NOIP2016 提高组 简要题解
    【题解】LOJ2759. 「JOI 2014 Final」飞天鼠(最短路)
    【题解】Comet OJ 国庆欢乐赛 简要题解
    【题解】P3645 [APIO2015]雅加达的摩天楼(分层图最短路)
    【题解】NOIP2017逛公园(DP)
    【题解】Comet OJ Round 70 简要题解
    【题解】 由乃(思博+欧拉定理+搜索)
    【题解】P5446 [THUPC2018]绿绿和串串(manacher)
    【题解】P4503 [CTSC2014]企鹅QQ(哈希)
    【题解】CF986E Prince's Problem(树上差分+数论性质)
  • 原文地址:https://www.cnblogs.com/zhaohaikun/p/12816975.html
Copyright © 2011-2022 走看看