mirror of
https://github.com/Kiritow/OJ-Problems-Source.git
synced 2024-03-22 13:11:29 +08:00
Create 3017.cpp
This commit is contained in:
parent
d9f30124cc
commit
3b18366ca6
62
POJ/3017.cpp
Normal file
62
POJ/3017.cpp
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user