1. 程式人生 > 實用技巧 >CF425A Sereja and Swaps(貪心+暴力列舉)(來自洛谷)

CF425A Sereja and Swaps(貪心+暴力列舉)(來自洛谷)

洛谷地址: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; }