CF425A Sereja and Swaps(貪心+暴力列舉)(來自洛谷)
阿新 • • 發佈:2020-07-14
洛谷地址: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; }