【TYVJ】1359 - 收入计划(二分)
生活随笔
收集整理的這篇文章主要介紹了
【TYVJ】1359 - 收入计划(二分)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
http://tyvj.cn/Problem_Show.aspx?id=1359
一開始是一眼看出是二分的,因為這里有單調性,因為取錢是一次取完并且是連續的。
所以最優取法就是準備達到某個價值再取。最優里邊包含了次優,也就是取不到m次我就能取完就一定能夠取m次能夠取完,只要在取法那里隨便取就行了,保證不超過這個某個價值
于是我們可以二分這個價值,看看能不能最優法取完并且次數小于m。
#include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> using namespace std; #define rep(i, n) for(int i=0; i<(n); ++i) #define for1(i,a,n) for(int i=(a);i<=(n);++i) #define for2(i,a,n) for(int i=(a);i<(n);++i) #define for3(i,a,n) for(int i=(a);i>=(n);--i) #define for4(i,a,n) for(int i=(a);i>(n);--i) #define CC(i,a) memset(i,a,sizeof(i)) #define read(a) a=getint() #define print(a) printf("%d", a) #define dbg(x) cout << #x << " = " << x << endl #define printarr(a, n, m) rep(aaa, n) { rep(bbb, m) cout << a[aaa][bbb]; cout << endl; } inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; } inline const int max(const int &a, const int &b) { return a>b?a:b; } inline const int min(const int &a, const int &b) { return a<b?a:b; }const int N=100005; int n, m, a[N];inline const bool check(const int &x) {int sum=0, t=0, i;for(i=1; i<=n; ++i) {sum+=a[i];if(sum>x) sum=a[i], ++t;if(t>=m) return 0; //這里要注意,因為此時一定還有沒取完的,所以==m的時候就要退出了}return 1; }int main() {read(n); read(m);int mx=0, sum=0;for1(i, 1, n) { read(a[i]); mx=max(mx, a[i]); sum+=a[i]; }int l=mx, r=sum, mid;while(l<=r) {mid=(l+r)>>1;if(check(mid)) r=mid-1;else l=mid+1;}print(r+1);return 0; }?因為范圍很大,所以我們二分的范圍要適當做點技巧。
?
?
?
?
描述 Description
????高考結束后,同學們大都找到了一份臨時工作,渴望掙得一些零用錢。從今天起,Matrix67將連續工作N天(1<=N& lt;=100?000)。每一天末他可以領取當天及前面若干天里沒有領取的工資,但他總共只有M(1<=M<=N)次領取工資的機會。 Matrix67已經知道了在接下來的這N天里每一天他可以賺多少錢。為了避免自己濫用零花錢,他希望知道如何安排領取工資的時間才能使得領到工資最多的 那一次工資數額最小。注意Matrix67必須恰好領工資M次,且需要將所有的工資全部領走(即最后一天末需要領一次工資)。輸入格式 InputFormat
????第一行輸入兩個用空格隔開的正整數N和M????以下N行每行一個不超過10000正整數,依次表示每一天的薪水。
輸出格式 OutputFormat
???輸出領取到的工資的最大值最小是多少。樣例輸入 SampleInput [復制數據]
7?5100
400
300
100
500
101
400
樣例輸出 SampleOutput [復制數據]
500數據范圍和注釋 Hint
【樣例說明】
????采取下面的方案可以使每次領到的工資不會多于500。這個答案不能再少了。
100?400???300?100???500???101???400???每一天的薪水
<------1?<-------2?<---3?<---4?<---5??領取工資的時間
??500???????400?????500???101???400???領取到的工資
總結
以上是生活随笔為你收集整理的【TYVJ】1359 - 收入计划(二分)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《C和指针》读书笔记 第5章-操作符和表
- 下一篇: Java坦克大战 (一) 之产生一个窗口