Description
Panagola, The Lord of city F likes to parade very much. He always inspects his city in his car and enjoys the welcome of his citizens. City F has a regular road system. It looks like a matrix with n+1 west-east roads and m+1 north-south roads. Of course, there are (n+1)*(m+1) road crosses in that system. The parade can start at any cross in the southernmost road and end at any cross in the northernmost road. Panagola will never travel from north to south or pass a cross more than once. Citizens will see Panagola along the sides of every west-east road. People who love Panagola will give him a warm welcome and those who hate him will throw eggs and tomatoes instead. We call a road segment connecting two adjacent crosses in a west-east road a “love-hate zone”. Obviously there are m love-hate zones in every west-east road. When passing a love-hate zone, Panagola may get happier or less happy, depending on how many people love him or hate him in that zone. So we can give every love-hate zone a “welcome value” which may be negative, zero or positive. As his secretary, you must make Panagola as happy as possible. So you have to find out the best route - of which the sum of the welcome values is maximal. You decide where to start the parade and where to end it.
When seeing his Citizens, Panagola always waves his hands. He may get tired and need a break. So please never make Panagola travel in a same west-east road for more than k minutes. If it takes p minutes to pass a love-hate zone, we say the length of that love-hate zone is p. Of course you know every love-hate zone’s length.
The figure below illustrates the case in sample input. In this figure, a best route is marked by thicker lines.
【题目分析】
单调队列优化DP
【代码】
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m,limit,ans=0;
int dp[102][10002];
int v[102][10002];
int l[102][10002];
int que[10002],hd,tl;
inline int read()
{
int ret=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9')
{
if (ch=='-') f=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9')
{
ret*=10;
ret+=ch-'0';
ch=getchar();
}
return ret*f;
}
//int main()
//{
// while (1)
// {
// memset(dp,0,sizeof dp);
// n=read();m=read();limit=read();
// if (!n&&!m&&!limit) return 0;
// for (int i=1;i<=n+1;++i) for (int j=1;j<=m;++j) v[i][j]=read(),v[i][j]+=v[i][j-1];
// for (int i=1;i<=n+1;++i) for (int j=1;j<=m;++j) l[i][j]=read(),l[i][j]+=l[i][j-1];
// for (int i=1;i<=n+1;++i)
// {
// for (int j=0;j<=m;++j)
// {
// dp[i][j]=dp[i-1][j];
// for (int k=0;k<j;++k)
// if (l[i][j]-l[i][k]<=limit)
// dp[i][j]=max(dp[i][j],dp[i-1][k]+v[i][j]-v[i][k]),ans=max(ans,dp[i][j]);
// for (int k=j+1;k<=m;++k)
// if (l[i][k]-l[i][j]<=limit)
// dp[i][j]=max(dp[i][j],dp[i-1][k]+v[i][k]-v[i][j]),ans=max(ans,dp[i][j]);
// }
// }
// printf("%d\n",ans);
// }
//}
int main()
{
while (1)
{
ans=0;
memset(dp,0,sizeof dp);
n=read();m=read();limit=read();
if (!n&&!m&&!limit) return 0;
for (int i=1;i<=n+1;++i) for (int j=1;j<=m;++j) v[i][j]=read(),v[i][j]+=v[i][j-1];
for (int i=1;i<=n+1;++i) for (int j=1;j<=m;++j) l[i][j]=read(),l[i][j]+=l[i][j-1];
for (int i=1;i<=n+1;++i)
{
int hd=1,tl=0;
for (int j=0;j<=m;++j)
{
dp[i][j]=dp[i-1][j];
while (hd<=tl&&l[i][j]-l[i][que[hd]]>limit) hd++;
while (hd<=tl&&dp[i-1][que[tl]]-v[i][que[tl]]<=dp[i-1][j]-v[i][j]) tl--;
que[++tl]=j;
dp[i][j]=max(dp[i][j],v[i][j]+dp[i-1][que[hd]]-v[i][que[hd]]);
ans=max(ans,dp[i][j]);
}
hd=1,tl=0;
for (int j=m;j>=0;--j)
{
while (hd<=tl&&l[i][que[hd]]-l[i][j]>limit) hd++;
while (hd<=tl&&dp[i-1][que[tl]]+v[i][que[tl]]<=dp[i-1][j]+v[i][j]) tl--;
que[++tl]=j;
dp[i][j]=max(dp[i][j],dp[i-1][que[hd]]+v[i][que[hd]]-v[i][j]);
ans=max(dp[i][j],ans);
}
}
printf("%d\n",ans);
}
}
本文介绍了一种使用单调队列优化动态规划的方法来确定城市中最佳游行路线的问题。该问题涉及在一个网格状的城市道路系统中寻找一条从南到北的路径,使得经过的欢迎值总和最大,同时考虑到领导人的体力限制。
140

被折叠的 条评论
为什么被折叠?



