hdu4374One hundred layer (DP+单调队列)

http://acm.hdu.edu.cn/showproblem.php?pid=4374

去年多校的题 今年才做 不知道这一年都干嘛去了。。

DP的思路很好想 dp[i][j] = max(dp[i-1][g]+sum[i][j]-sum[i][g-1],dp[i][j]) abs(g-j)<=t  不过复杂度是相当高的 所以呢 就出现了个单调队列 把它优化下

所谓的单调队列其实也就是一队列 始终保持着队头是最大的 若满足不了距离的条件 队头+1 队尾始终保持更新 让满足的了距离而且比队里的更大的元素进来

。。因为一初始化错了  WA了十多次啊 注意:有负数 

 1 #include <iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<stdlib.h>

 5 #include<algorithm>

 6 using namespace std;

 7 #define N 105

 8 #define M 10005

 9 #define LL __int64

10 int a[N][M],que[M];

11 int dp[N][M];

12 int s1[N][M],s2[N][M];

13 int main()

14 {

15     int i,j,n,m,x,t,str,end;

16     while(cin>>n>>m>>x>>t)

17     {

18         memset(dp,128,sizeof(dp));

19         memset(s1,0,sizeof(s1));

20         memset(s2,0,sizeof(s2));

21         for(i = 1; i <= n; i++)

22             for(j = 1; j <= m ; j++)

23             {

24                 scanf("%d",&a[i][j]);

25                 s1[i][j] = s1[i][j-1]+a[i][j];

26             }

27         for(i = 1 ; i <= n ;i++)

28             for(j = m ; j >= 1; j--)

29             s2[i][j] = s2[i][j+1]+a[i][j];

30         for(i = x ; i>=1&&i>=x-t ; i--)

31         dp[1][i] = s1[1][x]-s1[1][i-1];

32         for(i = x ; i <= m&&i<=x+t ; i++)

33         dp[1][i] = s2[1][x]-s2[1][i+1];

34         for(i = 2; i <= n ; i++)

35         {

36             str = 0;end=0;

37             for(j = 1;j <= m ; j++)

38             {

39                 while(str<end&&dp[i-1][j]-s1[i][j-1]>dp[i-1][que[end-1]]-s1[i][que[end-1]-1])

40                 end--;

41                 que[end++] = j;

42                 dp[i][j] = max(dp[i][j],dp[i-1][que[str]]-s1[i][que[str]-1]+s1[i][j]);

43                 if(j-que[str]>=t)

44                 str++;

45             }

46             str = 0;end=0;

47             for(j = m ; j >= 1; j--)

48             {

49                 while(str<end&&dp[i-1][j]-s2[i][j+1]>dp[i-1][que[end-1]]-s2[i][que[end-1]+1])

50                 end--;

51                 que[end++] = j;

52                 dp[i][j] = max(dp[i][j],dp[i-1][que[str]]-s2[i][que[str]+1]+s2[i][j]);

53                 if(que[str]-j>=t)

54                 str++;

55             }

56         }

57         int maxz=dp[n][1];

58         for(i = 1; i <= m ; i++)

59         maxz = max(maxz,dp[n][i]);

60         cout<<maxz<<endl;

61     }

62     return 0;

63 }
View Code

 

你可能感兴趣的:(HDU)