工资
(money/money.in/money.out) 時限1000ms 內存256MB 聰哥在暑假參加了打零工的活動,這個活動分為n個工作日,每個工作日的工資為Vi。有m個結算工錢的時間,聰哥可以自由安排這些時間,也就是說什么時候拿錢,老板說的不算,聰哥才有發言權!(因為聰哥是土豪,他是老板的老板) 聰哥不喜歡身上一次性有太多的錢,于是他想安排一下拿錢的時間,使他一次性拿的錢中最大的最小。(最后一天一定要領錢) 輸入 第一行 2個數 n,m 接下來n行,每行一個數,代表Vi. 輸出 最小的最大錢數。 樣例輸入 7 5 100 400 300 100 500 101 400 樣例輸出 500 樣例說明 100 400//300 100//500//101//400// “//”表示老大要去拿錢。 數據范圍 20% 1<=n<=20 另 20% 1<=n<=50,Vi的和不超過1000 100% 1<=n<=100,000,m<=n,Vi<=10,000題面
明顯,二分答案,是的最大的區間段和最小
還有一個限制條件,最后一天必須結算
判斷的時候加以分析就好了
分值:100/100
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<string> 5 #include<cstdio> 6 #include<queue> 7 #include<cmath> 8 #define ll long long 9 #define DB double 10 using namespace std; 11 inline int read() 12 { 13 int x=0,w=1;char ch=getchar(); 14 while(!isdigit(ch)){if(ch=='-') w=-1;ch=getchar();} 15 while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); 16 return x*w; 17 } 18 const int N=1e5+100; 19 int n,m,a[N],M; 20 ll ans,L,R,mid,k; 21 bool v[N]; 22 bool ok(ll x) 23 { 24 M=0;k=0;v[n]=0; 25 for(int i=1;i<=n;++i) 26 { 27 if(x<a[i]) return 0; 28 k+=a[i]; 29 if(k>x) M++,k=a[i],v[i-1]=1; 30 // cout<<k<<" "<<M<<" "<<i<<endl; 31 if(M>m) return 0; 32 } 33 if(k>x) return 0; 34 // cout<<k<<" "<<v[n]<<endl; 35 if(!v[n]){v[n]=1;M++;} 36 if(M<=m) return 1; 37 return 0; 38 } 39 int main() 40 { 41 freopen("money.in","r",stdin); 42 freopen("money.out","w",stdout); 43 n=read();m=read(); 44 for(int i=1;i<=n;++i) a[i]=read(),R+=a[i]; 45 // cout<<ok(38); 46 while(L<=R) 47 { 48 mid=(L+R)>>1; 49 if(ok(mid)) ans=mid,R=mid-1; 50 else L=mid+1; 51 } 52 printf("%lld",ans); 53 return 0; 54 }View Code
轉載于:https://www.cnblogs.com/adelalove/p/9032733.html
總結
- 上一篇: 甩点卡换多多卡
- 下一篇: BZOJ3930: [CQOI2015]