UVA714給出n個數分成m個部分,使和最大的最小
阿新 • • 發佈:2019-01-29
這題,小白書上有講,所以當時也沒多想直接二分,分完之後,發現有問題,他說前面的儘量小,這裡就要貪心,
從後面貪心,只要和值不大於二分的值就一直二分,然後發現還是不對,看了別人的,忽略了一個問題,二分的時候
x的初始值不能是零,因為我寫的判斷二分的函式比較特殊,所以如果判斷的值小於全部的數也能過,所以,這裡x的
初值注意取全部數的最大值。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cctype> #include<cmath> #include<algorithm> #include<string> #include<map> #include<queue> #include<stack> #include<set> #include<vector> #define LL long long using namespace std; const int maxn=1e4+10; const double eps=1e-6; int m,k; int a[510]; int ca[1110]; bool solve(LL t) { LL sum=0; int tem=k-1; for(int i=0;i<m;i++) { if(sum+a[i]>t) { sum=0; tem--; } if(tem<0) return 0; sum+=a[i]; } return 1; } int main() { int t; cin>>t; while(t--) { cin>>m>>k; LL x=0,y=0; for(int i=0;i<m;i++) { scanf("%d",&a[i]); x=max(x,(LL)a[i]); y+=a[i]; } if(k==1) { for(int i=0;i<m-1;i++) cout<<a[i]<<' '; cout<<a[m-1]<<endl; continue; } while(x<y) { LL tt=x+(y-x)/2; if(solve(tt)) y=tt; else x=tt+1; } // cout<<x<<endl; k--; int l=0; LL tem=a[m-1]; memset(ca,0,sizeof(ca)); ca[l++]=tem; for(int i=m-2;i>=0;i--) { if(k&&i+1==k) { ca[l++]=-1; ca[l++]=a[i]; k--; continue; } if(k&&tem+a[i]>x) { ca[l++]=-1; ca[l++]=a[i]; k--; tem=a[i]; } else { ca[l++]=a[i]; tem+=a[i]; } } for(int i=l-1;i>0;i--) { if(ca[i]==-1) cout<<"/ "; else cout<<ca[i]<<' '; } cout<<ca[0]<<endl; } return 0; }