【TYVJ】1359 - 收入计划(二分)
生活随笔
收集整理的這篇文章主要介紹了
【TYVJ】1359 - 收入计划(二分)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
http://tyvj.cn/Problem_Show.aspx?id=1359
一開始是一眼看出是二分的,因為這里有單調(diào)性,因為取錢是一次取完并且是連續(xù)的。
所以最優(yōu)取法就是準(zhǔn)備達(dá)到某個價值再取。最優(yōu)里邊包含了次優(yōu),也就是取不到m次我就能取完就一定能夠取m次能夠取完,只要在取法那里隨便取就行了,保證不超過這個某個價值
于是我們可以二分這個價值,看看能不能最優(yōu)法取完并且次數(shù)小于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; }?因為范圍很大,所以我們二分的范圍要適當(dāng)做點技巧。
?
?
?
?
描述 Description
????高考結(jié)束后,同學(xué)們大都找到了一份臨時工作,渴望掙得一些零用錢。從今天起,Matrix67將連續(xù)工作N天(1<=N& lt;=100?000)。每一天末他可以領(lǐng)取當(dāng)天及前面若干天里沒有領(lǐng)取的工資,但他總共只有M(1<=M<=N)次領(lǐng)取工資的機(jī)會。 Matrix67已經(jīng)知道了在接下來的這N天里每一天他可以賺多少錢。為了避免自己濫用零花錢,他希望知道如何安排領(lǐng)取工資的時間才能使得領(lǐng)到工資最多的 那一次工資數(shù)額最小。注意Matrix67必須恰好領(lǐng)工資M次,且需要將所有的工資全部領(lǐng)走(即最后一天末需要領(lǐng)一次工資)。輸入格式 InputFormat
????第一行輸入兩個用空格隔開的正整數(shù)N和M????以下N行每行一個不超過10000正整數(shù),依次表示每一天的薪水。
輸出格式 OutputFormat
???輸出領(lǐng)取到的工資的最大值最小是多少。樣例輸入 SampleInput [復(fù)制數(shù)據(jù)]
7?5100
400
300
100
500
101
400
樣例輸出 SampleOutput [復(fù)制數(shù)據(jù)]
500數(shù)據(jù)范圍和注釋 Hint
【樣例說明】
????采取下面的方案可以使每次領(lǐng)到的工資不會多于500。這個答案不能再少了。
100?400???300?100???500???101???400???每一天的薪水
<------1?<-------2?<---3?<---4?<---5??領(lǐng)取工資的時間
??500???????400?????500???101???400???領(lǐng)取到的工資
總結(jié)
以上是生活随笔為你收集整理的【TYVJ】1359 - 收入计划(二分)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《C和指针》读书笔记 第5章-操作符和表
- 下一篇: Java坦克大战 (一) 之产生一个窗口