hdu4374 One hundred layer

108 篇文章 0 订阅
5 篇文章 0 订阅

-0:09:37
                           
B - One hundred layer
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

Now there is a game called the new man down 100th floor. The rules of this game is:
   1.  At first you are at the 1st floor. And the floor moves up. Of course you can choose which part you will stay in the first time.
   2.  Every floor is divided into M parts. You can only walk in a direction (left or right). And you can jump to the next floor in any part, however if you are now in part “y”, you can only jump to part “y” in the next floor! (1<=y<=M)
   3.  There are jags on the ceils, so you can only move at most T parts each floor.
   4.  Each part has a score. And the score is the sum of the parts’ score sum you passed by.
Now we want to know after you get the 100th floor, what’s the highest score you can get.
 

Input

The first line of each case has four integer N, M, X, T(1<=N<=100, 1<=M<=10000, 1<=X, T<=M). N indicates the number of layers; M indicates the number of parts. At first you are in the X-th part. You can move at most  T parts in every floor in only one direction.
Followed N lines, each line has M integers indicating the score. (-500<=score<=500)
 

Output

Output the highest score you can get.
 

Sample Input

       
       
3 3 2 1 7 8 1 4 5 6 1 2 3
 

Sample Output

       
       
29
状态转移方程f[i][j]表示第i层,第j部分可以得到的分数,很明显,f[i][j]=max{f[i-1][k]+[k到是j的和 ]
当然,这个数据在10005这么大,不可能全部都搜出来,这样,我们只能用单调队列,来进行优化,但有一个问题 
sum[k-j]的值是和j有关的,我们应该明白,单调队列,是不能,存入与现在这个状态有关的变量,但这个现在的变题量,也只是在算到j的时候,才有意义,而且这个sum[j],我们完全可以在队列外直接加起来,这样,只能转化sum[k-j]=sum[j]-sum[k],这样f[i][j]=max(f[i-1][k]-sum[k]
+sum[j],这样,就可以用优先队列,把sum[k]+f[i-1][k]存入优先队列,这样就可以大大简化算的过程!
}
#include<stdio.h>
#include<queue>

#include<iostream>
using namespace std;
int dp[105][10005],sum[10005],val[105][10005];
struct floor {int id,x;};

int n,m,x,t;
#define inf -10000000
int fmax(int a,int b)
{
    if(a>b)
    return a;
    return b;
}
int fabs(int a)
{
	if(a<0)
return -a;
return a;
}
void init()
{
    int i,j;
    for( i=0;i<n;i++)
        for(j=1;j<=m;j++)
        {
            scanf("%d",&val[i][j]);

        }
    for(i=0;i<=n;i++)
        for(j=0;j<=m;j++)
        {
            dp[i][j]=inf;

        }
        dp[0][x]=val[0][x];
       int  cnt=val[0][x];

        for(i=0,j=x-1;i<t&&j>0;i++,j--)//向左走
        {
            cnt+=val[0][j];
            dp[0][j]=cnt;
        }
		cnt=val[0][x];
        for( i=0,j=x+1;i<t&&j<=m;i++,j++)//向右走累加起来 
        {
            cnt+=val[0][j];
            dp[0][j]=cnt;
        }


}
int makedp()
{
    deque<floor> q;
    floor temp;
    int i,j;
    for( i=1;i<n;i++)
    {
        sum[0]=0;
		q.clear();
        for(j=1;j<=m;j++)
        {
            while(!q.empty()&&(q.front().id<j-t))//右边
            {
               q.pop_front();
            }
            sum[j]=val[i][j]+sum[j-1];
            temp.x=dp[i-1][j]-sum[j-1];
            while(!q.empty()&&q.back().x<=temp.x)
            {
                q.pop_back();
            }
            temp.id=j;
            q.push_back(temp);
            if(!q.empty())
            {
                dp[i][j]=q.front().x+sum[j];
            }
        }
	    q.clear();
        sum[m+1]=0;
        for(j=m;j>0;j--)
        {
            while(!q.empty()&&(q.front().id>j+t))//左边
            {
                q.pop_front();
            }
            sum[j]=val[i][j]+sum[j+1];
            temp.x=dp[i-1][j]-sum[j+1];
            while(!q.empty()&&q.back().x<=temp.x)
            {
                q.pop_back();
            }
			temp.id=j;
            q.push_back(temp);
            if(!q.empty())
            {
                dp[i][j]=fmax(dp[i][j],q.front().x+sum[j]);
            }

        }

    }

     return 1;
}
int main ()
{
    int maxx=inf,i;
    while(scanf("%d%d%d%d",&n,&m,&x,&t)!=EOF)
    {

        init();
        makedp();
        maxx=dp[n-1][0];
        for( i=2;i<=m;i++)
        {
           maxx=fmax(maxx,dp[n-1][i]);
		 // printf("%d ",dp[n-1][i]);
        }
        printf("%d\n",maxx);
    }

    return 0;
}









 

FAQ | About Virtual Judge |  Forum |  Discuss |  Open Source Project
All Copyright Reserved ©2010-2012  HUST ACM/ICPC TEAM 
Anything about the OJ, please ask in the  forum, or contact author: Isun
Server Time:  2013-07-14 18:50:22
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值