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;
    }
    
  • 相关阅读:
    12个思维管理工具:标杆分析法、麦肯锡7步分析法、SMART原则....
    Capturing Audio in Android Q
    闭环思维
    如何下载Google Play商店的apk?如何安装分割的apk ?
    强制删除文件 或 文件夹
    ToDesk ---- 个人免费 极致流畅的远程协助软件
    无法显示内挂(非内嵌)字幕-
    MKVToolNix 一款Matroska(.mkv)格式编辑工具,可以将超过16条音轨/字幕封装到一个.mkv文件中去
    Symantec Endpoint Protection(赛门铁克杀毒软件) 如何添加白名单避免被误删、误杀?
    二维码识别工具
  • 原文地址:https://www.cnblogs.com/zhaohaikun/p/12816975.html
Copyright © 2011-2022 走看看