OJ-Problems-Source/POJ/3017.cpp

63 lines
1.6 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 1000100
#define INF 0x3f3f3f3f
long long a[MAXN];
long long dp[MAXN];
long long t[MAXN];
int tbegin,tend;
int main()
{
int N;
long long M;
scanf("%d %I64d",&N,&M);
tbegin=tend=0;
long long blocksum=0;
int blockbegin=0;
for(int i=1;i<=N;i++)
{
scanf("%I64d",&a[i]);
///如果整个数列中任何一个数超过M那么是无论如何都不能划分的(没有负数存在)
if(a[i]>M)
{
printf("-1\n");
return 0;
}
blocksum+=a[i];
while(blocksum>M)
{
///如果现在假设的连续区块 ID: blockbegin, blockbegin+1 ... i
///求和超过M那么这是一个非法区块需要减去最左端的区块(向右收缩)
blockbegin++;///【疑问】为什么blockbegin要在前面?
blocksum-=a[blockbegin];
}
///队列用于维护每个区块中最大的值的ID
while(tbegin<tend&&a[t[tend-1]]<=a[i]) tend--;
t[tend++]=i;
///队列中最左端的值的ID在blockbegin的左端弹出
while(tbegin<tend&&t[tbegin]<=blockbegin) tbegin++;
///未进行DP前初始化为INF
dp[i]=INF;
int maxvalbegin=blockbegin;
for(int index=tbegin;index<tend;index++)
{
long long tmp=dp[maxvalbegin]+a[t[index]];
dp[i]=min(dp[i],tmp);
maxvalbegin=t[index];
}
}
printf("%I64d\n",dp[N]);
return 0;
}