• hdu 4374 单调队列优化动态规划


    思路:我只想说,while(head<=rear&&que[rear].val+sum[j]-sum[que[rear].pos-1]<=dp[i-1][j]+num[i-1][j])表达式中,我把最后的num[i-1][j]丢了,检查了一整天啊!一整天!我那丢失的时间!

    寻找从上一层到该层中最优的转换点,如果该转化点到该点超过t就出队。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #define Maxn 110
    #define Maxm 10010
    #define inf 1000000000
    using namespace std;
    int dp[Maxn][Maxm],sum[Maxm],num[Maxn][Maxm];
    int que[Maxm*5];
    void init()
    {
        memset(sum,0,sizeof(sum));
        memset(num,0,sizeof(num));
    }
    inline int ReadInt()
    {
        int flag = 1;
        char ch;
        int a = 0;
        while((ch = getchar()) == ' ' || ch == '
    ');
        if(ch == '-') flag = -1;
        else
        a += ch - '0';
        while((ch = getchar()) != ' ' && ch != '
    ')
        {
            a *= 10;
            a += ch - '0';
        }
        return flag * a;
    }
    int main()
    {
        int n,m,x,t,i,j,head,rear;
        while(scanf("%d%d%d%d",&n,&m,&x,&t)!=EOF){
            init();
            for(i=1;i<=n;i++){
                for(j=1;j<=m;j++){
                    num[i][j]=ReadInt();
                    dp[i][j]=-inf;
                }
            }
            memset(dp[0],-50,sizeof(dp));
            dp[0][x]=0;
            for(i=1;i<=n;i++){
                memset(sum,0,sizeof(sum));
                head=1,rear=0;
                for(j=1;j<=m;j++){
                    sum[j]=sum[j-1]+num[i][j];
                    while(head<=rear&&dp[i-1][que[rear]]+sum[j]-sum[que[rear]-1]<=dp[i-1][j]+num[i][j])
                        rear--;
                    que[++rear]=j;
                    while(j-que[head]>t&&head<=rear)
                        head++;
                    if(head<=rear)
                    dp[i][j]=dp[i-1][que[head]]+sum[j]-sum[que[head]-1];
                }
                head=1,rear=0;
                memset(sum,0,sizeof(sum));
                for(j=m;j>=1;j--){
                    sum[j]=sum[j+1]+num[i][j];
                    while(head<=rear&&dp[i-1][que[rear]]+sum[j]-sum[que[rear]+1]<=dp[i-1][j]+num[i][j])
                        rear--;
                    que[++rear]=j;
                    while(que[head]-j>t&&head<=rear)
                        head++;
                    if(head<=rear)
                    dp[i][j]=max(dp[i][j],dp[i-1][que[head]]+sum[j]-sum[que[head]+1]);
                }
            }
            int ans=-inf;
            for(i=1;i<=m;i++)
                ans=max(ans,dp[n][i]);
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    第一次系统实践作业
    第03组 Beta版本演示
    第03组 Beta冲刺(4/4)
    第03组 Beta冲刺(3/4)
    第03组 Beta冲刺(2/4)
    第03组 Beta冲刺(1/4)
    Java程序(文件操作)
    Java程序(事件监听与计算机界面)
    Java(个人信息显示界面)
    Java(学生成绩管理)
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3239376.html
Copyright © 2020-2023  润新知