POJ 3017 單調佇列dp
Time Limit: 2000MS | Memory Limit: 131072K | |
Total Submissions: 8764 | Accepted: 2576 |
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
把序列分成若干部分,每一部分的和不超過m,求每一部分裡最大值和的最小值。
開始沒啥思路,研究了半天,感覺單調佇列dp非常的精妙,先mark一下,後面慢慢理解吧。
程式碼:
/* ***********************************************
Author :_rabbit
Created Time :2014/5/13 1:35:25
File Name :C.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
ll que[100100],a[100100],dp[100100];
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
//dp 方程:f[i]=f[j]+max(x[j+1],x[j+2],...,x[i]),其中j<i,x[j+1]+x[j+2]+...+x[i]<=m;
ll n,m;
while(~scanf("%lld%lld",&n,&m)){
bool flag=1;
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
if(a[i]>m)flag=0;
}
if(!flag){
puts("-1");continue;
}
ll front=0,rear=0,p=1;
dp[1]=a[1];que[rear++]=1;
ll sum=a[1];
for(ll i=2;i<=n;i++){
sum+=a[i];
while(sum>m)sum-=a[p++];//區間和小於等於m
while(front<rear&&a[i]>=a[que[rear-1]])rear--;//單調嚴格遞減佇列
que[rear++]=i;
while(que[front]<p&&front<rear)front++;//把遠離的彈出。
dp[i]=dp[p-1]+a[que[front]];
for(ll j=front+1;j<rear;j++)
dp[i]=min(dp[i],dp[que[j-1]]+a[que[j]]);//列舉佇列中的元素,求最優解。
}
cout<<dp[n]<<endl;
}
return 0;
}
相關文章
- poj3017 dp+單調佇列佇列
- POJ 2823 單調佇列佇列
- hdu 3401 單調佇列+DP佇列
- 單調佇列最佳化 DP佇列
- hdu4374單調佇列+dp佇列
- [學習筆記] 單調佇列最佳化DP - DP筆記佇列
- HDU 3530 Subsequence (dp+單調佇列)佇列
- 單調佇列佇列
- 單調棧/單調佇列佇列
- 單調佇列雙端佇列佇列
- POJ 2823Sliding Window(單調佇列水題)佇列
- 單調棧和單調佇列佇列
- 單調棧 和 單調佇列佇列
- POJ2823 Sliding Window (單調佇列的基本應用)佇列
- hdu 3415 單調佇列佇列
- BZOJ1044: [HAOI2008]木棍分割(dp 單調佇列)佇列
- 聯賽模擬測試18 A. 施工 單調佇列(棧)優化DP佇列優化
- HDU3415 Max Sum of Max-K-sub-sequence (DP+單調佇列)佇列
- HDU 3530 單調佇列佇列
- hdu 4122 單調佇列佇列
- BZOJ 2442 [Usaco2011 Open]修剪草坪:單調佇列優化dp佇列優化
- 佇列-單端佇列佇列
- POJ 3253 Fence Repair 優先佇列AI佇列
- 單調佇列優化dp(五)——#10179. 「一本通 5.5 例 5」Banknotes佇列優化
- POJ 2259 Team Queue【模擬佇列】佇列
- POJ 1724 ROADS(優先佇列+spfa)佇列
- POJ2431 Expedition (優先佇列)佇列
- POJ 2051(最小堆/優先佇列)佇列
- noi.ac #289. 電梯(單調佇列)佇列
- 決策單調性DP
- bzoj1597: [Usaco2008 Mar]土地購買(斜率優化+Dp+單調佇列)優化佇列
- 洛谷P4544 [USACO10NOV] Buying Feed G 題解 單調佇列最佳化DP佇列
- 多重揹包問題的單調佇列優化佇列優化
- HDU3530 單調佇列的應用佇列
- 洛谷P3195 [HNOI2008]玩具裝箱TOY(單調佇列優化DP)佇列優化
- C語言 簡單的佇列(陣列佇列)C語言佇列陣列
- hdu3415 單調佇列求區間最大和佇列
- hdu 4122Alice's mooncake shop(單調佇列)佇列