标签:scan col 等于 queue pen ace ide mat can
1.贪心
k个点,进行k次分配,每次选取最稀疏的区间,更新该区间的稀疏度,并用优先队列优化。
时间复杂度为O(klogn)
1 //贪心 时间复杂度为klogn 2 #include <cmath> 3 #include <queue> 4 #include <cstdio> 5 using namespace std; 6 7 const int N=1e3+10; 8 struct node{ 9 int cnt,d; 10 double x; 11 friend bool operator < (node n1,node n2){ 12 return n1.x < n2.x; 13 } 14 }p[N]; 15 priority_queue <node> q; 16 17 int main(){ 18 int n,m,k,pre,cur; 19 scanf("%d%d%d%d",&n,&m,&k,&pre); 20 for(int i=2;i<=n;i++){ 21 scanf("%d",&cur); 22 p[i].cnt=1; 23 p[i].d=cur-pre; 24 p[i].x=1.0*p[i].d/p[i].cnt; 25 q.push(p[i]); 26 pre=cur; 27 } 28 for(int i=1;i<=k;i++){ 29 node tmp=q.top(); 30 q.pop(); 31 tmp.cnt++; 32 tmp.x=1.0*tmp.d/tmp.cnt; 33 q.push(tmp); 34 } 35 node tmp=q.top(); 36 tmp.x=floor(tmp.x*10+0.5); 37 printf("%.1f\n",tmp.x/10); 38 return 0; 39 }
2.二分答案
先由n个点得到n-1个区间,计算在答案为d的条件下,每个区间还需要多少点,如果总和小于等于k,那么该答案是符合条件,从这些答案中选取最小的即可。
1 //二分答案 2 #include <cstdio> 3 using namespace std; 4 5 const double eps=1e-8; 6 const int N=1e3+10; 7 int n,m,k; 8 double a[N]; 9 10 int check(double val){ 11 int cnt=0; 12 for(int i=2;i<=n;i++){ 13 cnt+=int(a[i]/val); 14 } 15 if(cnt<=k) return true; 16 return false; 17 } 18 19 int main(){ 20 double ans,pre,cur; 21 scanf("%d%d%d%lf",&n,&m,&k,&pre); 22 for(int i=2;i<=n;i++){ 23 scanf("%lf",&cur); 24 a[i]=cur-pre; 25 pre=cur; 26 } 27 double l=0,r=100000; 28 while(r-l>eps){ 29 double mid=(l+r)/2; 30 if(check(mid)) {ans=mid;r=mid;} 31 else l=mid; 32 } 33 printf("%.1f\n",ans); 34 return 0; 35 }
hiho 第216周 Gas Stations(贪心 | 二分答案)
标签:scan col 等于 queue pen ace ide mat can
原文地址:https://www.cnblogs.com/ehanla/p/9505167.html