Dinner 点餐
来源:互联网 发布:中欧工程技术学院知乎 编辑:程序博客网 时间:2024/05/16 05:29
二分答案。
关键在于check()的写法。
20分的写法:
check(x) 中O(n*n)的写法:直接枚举起点,一直往后加,一旦>x,就加一张菜单,如此枚举。
60分的写法:
二分加二分。用一个前缀和来优化。
check(x)中枚举起点s,设当前这一张菜单的起点为L,那么下一个起点就是sum[L]+x的前驱,可以用upper_bound()来找,然后再把找出来的那个位置减 1 ,就是下一个起点L,菜单数加 1。直到L>=s+n就停止。再把菜单数与m进行比较。
100分的写法
在20分的基础上加上一句优化。
for(int s=1;skp<=x;s++,skp+=t[s])
check
int check(LL x){ int tt; LL p,skp=0; for(int s=1;skp<=x;s++,skp+=t[s]) { tt=1,p=t[s]; for(int i=s+1;i<s+n;i++) { if(p+t[i]>x) { p=t[i]; tt++; } else p+=t[i]; } if(tt<=m) return true; //只要有成立的,就要缩小答案 } return false;}
见图
skp( B这一段) 如果>x,一定会在后面使用一个菜单,那么就相当于在前面时B使用菜单一样,如果这样成立的话,那么在前面枚举s是也会成立,运行到这一步,就说明前面不成立,那么现在也不会成立;
20分代码
#include<iostream>#include<cstring>#include<cstdio>#define LL long long#define N 50009using namespace std;int n,m,t[2*N];LL L,R,mid;bool check(LL x){ int tt; LL p; for(int s=1;s<=n;s++) { tt=1,p=t[s]; for(int i=s+1;i<s+n;i++) { if(p+t[i]>x) { p=t[i]; tt++; } else p+=t[i]; } if(tt<=m) return true; } return false;}int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&t[i]); R+=t[i],L=max(L,1ll*t[i]); t[i+n]=t[i]; } while(L<=R) { mid=(L+R)>>1; if(check(mid)) R=mid-1; else L=mid+1; } printf("%lld",L); return 0;}
60分代码
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#define LL long long#define N 50009using namespace std;int n,m,t[2*N];LL L,R,mid,sum[2*N];bool check(LL x){ int tt,l; for(int s=1;s<=n;s++) { l=s;tt=0; while(l<s+n) { l=upper_bound(sum+l,sum+s+n+1,sum[l]+mid)-sum-1; tt++; } if(tt<=m) return true; } return false;}int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&t[i]); R+=t[i],L=max(L,1ll*t[i]); t[i+n]=t[i]; } for(int i=1;i<=2*n;i++) sum[i]+=sum[i-1]+t[i]; while(L<=R) { mid=(L+R)>>1; if(check(mid)) R=mid-1; else L=mid+1; } printf("%lld",L); return 0;}
100分代码
#include<iostream>#include<cstring>#include<cstdio>#define LL long long#define N 50009using namespace std;int n,m,t[2*N];LL L,R,mid;int check(LL x){ int tt; LL p,skp=0; for(int s=1;skp<=x;s++,skp+=t[s]) { tt=1,p=t[s]; for(int i=s+1;i<s+n;i++) { if(p+t[i]>x) { p=t[i]; tt++; } else p+=t[i]; } if(tt<=m) return true; } return false;}int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&t[i]); R+=t[i],L=max(L,1ll*t[i]); t[i+n]=t[i]; } while(L<=R) { mid=(L+R)>>1; if(check(mid)) R=mid-1; else L=mid+1; } printf("%lld",L); return 0;}
阅读全文
0 0
- Dinner 点餐
- 参加 dinner 的 注意点
- Dinner
- Dinner
- Dinner
- Dinner
- Dinner
- Dinner
- Dinner
- dinner
- Dinner
- Dinner
- Dinner
- Dinner
- Dinner
- Dinner
- Dinner
- Dinner
- CSS 常用样式 提高网页编写速度
- 提示没有Windows管理员权限? 2招就能找回来!
- 566. Reshape the Matrix
- Mybatis-新增
- run in term
- Dinner 点餐
- 用 C 语言编写 Windows 服务程序的五个步骤
- Luogu 1282(dp)
- 排序算法—插入排序(python)
- HDU 6166 && 2017 多校训练:Senior Pan(最短路)
- Bootstrap fileinput.js Demo
- Linux 查看log文件
- ACM集训日记-8月22日
- git的基本使用