有 N 头牛排成一列,有的面朝前,有的面朝后。
每次操作可以选择任意连续的 K 头牛,并改变它们的朝向。
请求出最小的 K,使得将所有牛的朝向都变为朝前所需的操作次数最少。
我们去枚举 ,然后贪心去check
复杂度
#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; }