這道題的狀態是dp[i][j],代表走到第i,j的位置時的收入v,採用填表法,到達i,j的選擇有三種,一種是dp[i][j]=dp[i-1][j],就是直接從上一行的第j個路口走到這一行的j路口,還有就是從左往右在i行走到j,或者從右往左,轉移方程分別是 從左向右dp[i][j]=max(dp[i-1][k]+sum[i][j]-sum[i][k]) , kj
所以送左向右需要找到 dp[i-1][k]-sum[i][k]的最大值, 從右向左需要找到 dp[i-1][k]+sum[i][k]的最大值
為了快速找到合適的k,使用優先佇列 或者 單調佇列 進行優化
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
typedef
long
long ll;
const
int maxn=
105,maxm=
10000+5
;int n,m,k,value[maxn]
[maxm]
,cost[maxn]
[maxm]
,dp[maxn]
[maxm]
,q[maxm]
,front,rear;
intmain
(void)}
for(
int i=
1;i<=n+1;
++i)
}for
(int i=
1;i<=n+1;
++i)
front=0;
rear=-1
;//左到右
for(
int j=
0;j<=m;
++j)
int t=dp[i-1]
[j]-value[i]
[j];
while
(front<=rear && t>=dp[i-1]
[q[rear]
]-value[i]
[q[rear]])
--rear;
q[++rear]
=j;}
//從右到左
front=0;
rear=-1
;for
(int j=m;j>=0;
--j)
int t=dp[i-1]
[j]+value[i]
[j];
while
(front<=rear && t>=dp[i-1]
[q[rear]
]+value[i]
[q[rear]])
--rear;
q[++rear]
=j;}
}int ans=dp[n+1]
[0];
for(
int j=
0;j<=m;
++j)
printf
("%d\n"
,ans);}
return0;
}//2 2 2
//7 8
//4 5
//1 2
//1 1
//1 1
//1 1
//0 0 0
//1 2 2
//4 5
//1 2
//1 1
//1 1
//0 0 0
ZZULIOJ 1427 數字轉換
time limit 1 sec memory limit 128 mb submit 542 solved 144 submit status web board 老師交給小明乙個任務,有兩個數字x和y x 通過以下兩種操作 一 將x乘以 2 二 將 x的值加上 1。小明希望能通過盡可能少的操作來...
1427 二分搜尋
題目描述 在有序序列中查詢某一元素x。輸入 首先輸入乙個正整數n n 100000 表示該序列有n個整數,然後按從小到大的順序輸入n個整數 接著是乙個正整數m,表示有m次查詢 最後是m個整數,表示m個要查詢的整數x。輸出 對於每乙個次查詢,有一行輸出。若序列中存在要查詢的元素x,則輸出元素x在序列中...
TYVJ 1427 小白逛公園
描述 小新經常陪小白去公園玩,也就是所謂的遛狗啦 在小新家附近有一條 公園路 路的一邊從南到北依次排著n個公園,小白早就看花了眼,自己也不清楚該去哪些公園玩了。一開始,小白就根據公園的風景給每個公園打了分 小新為了省事,每次遛狗的時候都會事先規定乙個範圍,小白只可以選擇第a個和第b個公園之間 包括a...