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 }