20分,有大佬吗?测试完成链接在最后

P2678 [NOIP2015 提高组] 跳石头

``` #include<iostream> #include<cstring> using namespace std; const int N = 5e4+100; /* 题目分析: 考虑朴素算法: 即统计从n快石头中选择m快石头删去,时间复杂度为 c(n,m) 再统计每种情况下的最短距离,复杂度为O(n) 最终时间复杂度为显然大于O(N^2) 显然超时 可以枚举最短的距离,通过最短距离反推需要移动的石头数量 如果需要的石头数量>m,说明距离此距离太大,应该让距离小一些 r = mid - 1 如果需要的石头数量<=m,说明距离太小了,应该让距离尽可能的大一些 ans = mid l = mid + 1,ans记录可能的答案 这样时间复杂度为O(nlogn) */ int f[N],bac[N],dis[N]; int l,n,m; int check(int u){ int cnt = 0; memcpy(bac,dis,sizeof(dis)); for (int i=2;i<=n+2;i++){ if (bac[i]<u){ cnt++; bac[i+1]+=bac[i]; } } return cnt; } int main(){ scanf("%d%d%d",&l,&n,&m); f[1] = 0; for (int i=2;i<=n+1;i++){ scanf("%d",&f[i]); } f[n+2] = l; for (int i=2;i<=n+2;i++){ dis[i] = f[i]-f[i-1]; //记录与前一点的距离 } int l = 1,r = 1e9,ans = -1; while (l<=r){ int mid = (l+r)>>1; if (check(mid)>m){ r = mid - 1; }else{ ans = mid; l = mid + 1; } } cout<<ans<<endl; return 0; } ```
by Lawliet142857 @ 2023-03-20 01:35:31


|