Time Limit: 2000MS | Memory Limit: 131072K | |
Total Submissions:11012 | Accepted: 3359 |
Description
Given an integer sequence { an } of length N, you are to cut the sequence into several parts every one of which is a consecutive subsequence of the original sequence. Every part must satisfy that the sum of the integers in the part is not greater than a given integer M. You are to find a cutting that minimizes the sum of the maximum integer of each part.
Input
The first line of input contains two integer N (0 < N ≤ 100 000), M. The following line contains N integers describes the integer sequence. Every integer in the sequence is between 0 and 1 000 000 inclusively.
Output
Output one integer which is the minimum sum of the maximum integer of each part. If no such cuttings exist, output −1.
Sample Input
8 17 2 2 2 8 1 8 2 1
Sample Output
12
Hint
Use 64-bit integer type to hold M.
#include <iostream>
#include <cstdio>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
using namespace std;
#define rep(x,y) for(int i=x;i<=y;i++)
#define repp(x,y,m,n) rep(x,m)rep(y,n)
typedef long long ll;
const int MAX=100000+5;
ll N,M;
int a[MAX];
int deq[MAX];
ll dp[MAX];
void print(){
for(int i=1;i<=N;i++){
cout<<dp[i]<<" ";
}
cout<<endl;
}
void solve(){
scanf("%lld %lld",&N,&M);
bool f=0;
for(int i=1;i<=N;i++){
scanf("%d",&a[i]);
if(a[i]>M){
f=1;
}
}
if(f){
printf("-1");
return;
}
int h=1,t=1;
int j=1;
ll sum=0;
for(int i=1;i<=N;i++){
while(h!=t&&a[deq[t-1]]<=a[i]){
t--;
}
sum+=a[i];
deq[t++]=i;
while(sum>M){
sum-=a[j++];
}
while(deq[h]<j){
h++;
}
dp[i]=dp[j-1]+a[deq[h]];
for(int k=h+1;k<t;k++){
dp[i]=min(dp[i],dp[deq[k-1]]+a[deq[k]]);
}
// print();
}
printf("%lld",dp[N]);
return;
}
int main(){
solve();
return 0;
}