AcWing 1353. 滑雪场设计

原题链接

考察:枚举

错误思路:

              第一想法是两个对顶堆维护最大值和最小值,但是遇到这样的 0 2 21 0 19 的数据会出错.原因是当第一次修改a[n]与a[1]符合距离17后,与a[2]不一定符合距离17,但是题目约定只能修改一次a2+b2 <= (a+b)2这样会使得结果小了.同理每次sort也一样.

正确思路:

              最大值最小值相差不超过17,换言之就是每座山都在长度17的区间内.0~100有84个长度17的区间,枚举每个区间,如果山在区间内就不修改,不在就修改.

此思路涉及证明:为什么所有山修改后在0~100区间内:

              情况一:所有山都不在0~100的区间内.假设最优解所有山都<0,在起初时所有山都是>0的,花费是两点距离的平方.但是如果我们把所有山的高度都修改为0,此方案也为合法方案,且距离比假设的最优解小.因此不可能全在0~100的区间内.

              情况二:部分山不在0~100的区间内.同理将这些不在区间内的山修改为0||100,可以发现花费也比最优解小.因此所有最优解都在0~100的范围内.

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 using namespace std;
 6 const int N = 1010,INF = 0x3f3f3f3f;
 7 int a[N];
 8 int main()
 9 {
10     int n;
11     scanf("%d",&n);
12     for(int i=1;i<=n;i++)
13         scanf("%d",&a[i]);
14     int ans = INF;
15     for(int l=1;l<=83;l++)
16     {
17         int r = l+17,sum = 0;
18         for(int i=1;i<=n;i++)
19         {
20             if(a[i]<l) sum+=(l-a[i])*(l-a[i]);
21             else if(a[i]>r) sum+=(r-a[i])*(r-a[i]);
22         }
23         ans = min(sum,ans);
24     }
25     printf("%d\n",ans);
26     return 0;
27 }

 

posted @ 2021-02-23 14:08  acmloser  阅读(63)  评论(0编辑  收藏  举报