ZOJ——Copying Books 最大值最小化問題 (貪心 + 二分)
阿新 • • 發佈:2018-11-16
#include <cstdio> #include <cmath> #include<vector> #include<cstring> #include<algorithm> #include<cmath> #include<stack> #include<string> #include<iostream> #include<set> #include<vector> using namespace std; #define maxn 505 int m,k; long long arr[maxn],sum,Min,ans; bool vis[maxn]; int divide(long long M) { memset(vis,0,sizeof(vis)); int cnt=0; int pos=m-1; while(pos>=0) { long long sum=0; bool ok=true; while(pos>=0&&sum+arr[pos]<=M) { ok=false; sum+=arr[pos]; --pos; } if(ok) { return k+1; } if(pos>=0) vis[pos]=true;//這裡想了hin久,就是如果和不超過M,但是k還少的話,下一個函式就要加上/ ++cnt; } return cnt; } long long binary() { long long left=Min,right=sum,mid; while(left<right) { mid=(left+right)/2; if(divide(mid)<=k) right=mid; else left=mid+1; } return right; } void output() { int cnt=divide(ans); for(int i=0;i<m-1&&cnt<k;++i) { if(!vis[i]) { vis[i]=true; ++cnt; } } for(int i=0;i<m;++i) { if(i) printf(" %lld",arr[i]); else printf("%lld",arr[i]); if(vis[i]) printf(" /"); } puts(""); } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&m,&k); sum=0; Min=0; for(int i=0;i<m;i++) { scanf("%lld",&arr[i]); sum+=arr[i]; if(arr[i]>Min) Min=arr[i]; } ans=binary(); output(); } return 0; }