AcWing 1248. 灵能传输

原题链接

考察:贪心

这道题和均分纸牌有点像,但是做法不完全一样

思路:

        参考均分纸牌问题,考虑操作对前缀和数组的影响,可以发现每交换一次sum[i-1]变成了sum[i],而sum[i]变成了sum[i-1](0<i<n),根据取值范围可以发现i=0与i=n是不能交换的,所以我们只能分配sum[i](0<i<n)的位置,使得sum[i]-sum[i-1]尽可能小.假设sum[0]是最小值,sum[n]为最大值,如果要让差值最小,需要sum数组曲线呈递增排列(可以画图证明).但如果不是最值,我们需要让曲线尽量保持单调,假设sum[0]<sum[n],那么最小值放在sum[0]一侧,最大值放在sum[n]一侧,可以使得差值更小.

        由图,我们要沿着蓝线在数轴上取值(不重复),构成一个新的序列(开头必为sum[0],结尾必为sum[n]),使得此序列sum[i]-sum[i-1]最小.可以发现从sum[0]~min要走一段重复的路程,在这段路程上我们要在上面取点sum[i],很显然我们需要有选择地取点,使得每个相邻的sum[i]差值最小.此处的贪心策略是每两个取一个点.如果sum[0]->min处就取所有点,那么返回时就只能直接从min~sum[1],此时跨度一定比每两个去点大.沿着蓝线可以发现我们可能会经过一次sum[n],但是sum[n]是一定放在最后的,因此我们可以采用双指针算法从sum[0]和sum[n]都开始取点.为了避免重复,可以用bool数组标记.

       这里注意是假设了sum[0]<sum[n],所以让min靠近sum[0],如果sum[0]>sum[n]就与之相反.

 

     

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N = 300010;
 6 typedef long long LL;
 7 int n;
 8 bool st[N];
 9 LL ans,sum[N],a[N];
10 int main()
11 {
12     int T;
13     scanf("%d",&T);
14     while(T--)
15     {
16         scanf("%d",&n);
17         ans = 0;
18         sum[0] = 0;
19         memset(st,0,sizeof st);
20         for(int i=1;i<=n;i++) scanf("%lld",&sum[i]),sum[i]+=sum[i-1];
21         LL f = sum[0],e = sum[n];
22         int l = 0,r = n;
23         if(f>e) swap(f,e);//如果不互换,那么s[0]向左找的时候可能与s[n]重叠.
24         sort(sum,sum+n+1);
25         for(int i=0;i<=n;i++)
26            if(sum[i]==f)
27            {
28                f = i;
29                break;
30            }
31         for(int i=n;i>=0;i--)
32            if(sum[i]==e)
33            {
34                e = i;
35                break;
36            }
37         for(int i=f;i>=0;i-=2)//s[0]放在第一个
38             a[l++] = sum[i],st[i] = 1;
39         for(int i=e;i<=n;i+=2)//s[n]放在最后一个
40             a[r--] = sum[i],st[i] = 1;
41         for(int i=0;i<=n;i++)
42             if(!st[i]) a[l++] = sum[i];
43         for(int i=1;i<=n;i++)
44             ans = max(ans,abs(a[i]-a[i-1]));
45         printf("%lld\n",ans);
46     }
47     return 0;
48 }

 

posted @ 2021-02-27 16:15  acmloser  阅读(68)  评论(0编辑  收藏  举报