洛谷地址:https://www.luogu.com.cn/problem/CF425A
题意:
给一个长为 n 的序列,以及交换次数 k,每次可以在原先的序列 中任意交换两个数 交换后找一个最大子串和,输出其可能的最大值。 1 <= n <= 200; 1 <=k <=10
解析:
n=200,可以通过暴力枚举每一个区间,来更新最大的区间和。
n*n枚举:i=1,j=2,3,4.....
i=2,j=2,3,4,.....
需要求的是i~j的这段区间
贪心思路:
一段区间,要想sum变大,需要把小的替换掉,要想最优,肯定是把区间外的最大值替换掉区间内的最小值。
针对每一次的[i,j]区间,给它进行k次替换。
总结:
[1,i-1]取最大,[j+1,n]取最大,两者取最大,替换[i,j]的最小。
#include<cstdio> #include<stack> #include<map> #include<set> #include<cmath> #include<queue> #include<cstring> #include<iostream> #include<algorithm> using namespace std; priority_queue<int,vector<int>,greater<int> > q;//ó??è?aD?μ?ó??è?óáD typedef long long ll; const int ma=2e2+20; const int maxn=2000010; int pos[ma]; int top=0; int ok=0; struct node { int x,id; }st[maxn]; bool cmp(node a , node b) { if(a.x==b.x) return a.id<b.id; return a.x<b.x; } int main() { // 4 0 20 int n,k; cin>>n>>k; for(int i=1;i<=n;i++) cin>>pos[i]; int summx=-maxn; for(int i=1;i<=n;i++) { for(int j=i;j<=n;j++) { int a[ma]; for(int c=1;c<=n;c++) a[c]=pos[c]; for(int kk=1;kk<=k;kk++) { int minn=maxn; int maxx=-maxn; int x1,x2; for(int c=1;c<i;c++) { if(maxx<a[c]) { maxx=a[c]; x1=c; } } for(int c=i;c<=j;c++) { if(minn>a[c]) { minn=a[c]; x2=c; } } for(int c=j+1;c<=n;c++) { if(maxx<a[c]) { maxx=a[c]; x1=c; } } if(minn<maxx) { swap(a[x1],a[x2]); } else break; } int sum=0; for(int c=i;c<=j;c++) sum+=a[c]; summx=max(summx,sum); } } cout<<summx<<endl; }