zoukankan      html  css  js  c++  java
  • MUTC8 E- One hundred layer 单调队列dp

    One hundred layer

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 1257    Accepted Submission(s): 467


    Problem 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
     

    Source
     

    Recommend
    zhuyuanchen520
     

    --------

    dp[i][j] = dp[i-1][k] + dis(k,j); 
    dp[i][j] = dp[i-1][1] + dis(1,j); 
    dp[i][j] = dp[i-1][2] + dis(2,j); 
    ... 
    转换为 
    dp[i][j] = dp[i-1][1] + dis(1,j); 
    dp[i][j] = dp[i-1][1] + dis(2,j)+[dis(2,j)-dis(1,j)]; 
    ... 
    这样只要比较dis(1,j)和dis(2,j)+[dis(2,j)-dis(1,j)] ... 
    在距离限制内维护一个单调队列可以O(1)取到最值  

    --------

    /** head-file **/
    
    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <iomanip>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <list>
    #include <set>
    #include <map>
    #include <algorithm>
    
    /** define-for **/
    
    #define REP(i, n) for (int i=0;i<int(n);++i)
    #define FOR(i, a, b) for (int i=int(a);i<int(b);++i)
    #define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)
    #define REP_1(i, n) for (int i=1;i<=int(n);++i)
    #define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)
    #define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)
    #define REP_N(i, n) for (i=0;i<int(n);++i)
    #define FOR_N(i, a, b) for (i=int(a);i<int(b);++i)
    #define DWN_N(i, b, a) for (i=int(b-1);i>=int(a);--i)
    #define REP_1_N(i, n) for (i=1;i<=int(n);++i)
    #define FOR_1_N(i, a, b) for (i=int(a);i<=int(b);++i)
    #define DWN_1_N(i, b, a) for (i=int(b);i>=int(a);--i)
    
    /** define-useful **/
    
    #define clr(x,a) memset(x,a,sizeof(x))
    #define sz(x) int(x.size())
    #define see(x) cerr<<#x<<" "<<x<<endl
    #define se(x) cerr<<" "<<x
    #define pb push_back
    #define mp make_pair
    
    /** test **/
    
    #define Display(A, n, m) {                      
        REP(i, n){                                  
            REP(j, m) cout << A[i][j] << " ";       
            cout << endl;                           
        }                                           
    }
    
    #define Display_1(A, n, m) {                    
        REP_1(i, n){                                
            REP_1(j, m) cout << A[i][j] << " ";     
            cout << endl;                           
        }                                           
    }
    
    using namespace std;
    
    /** typedef **/
    
    typedef long long LL;
    
    /** Add - On **/
    
    const int direct4[4][2]={ {0,1},{1,0},{0,-1},{-1,0} };
    const int direct8[8][2]={ {0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1} };
    const int direct3[6][3]={ {1,0,0},{0,1,0},{0,0,1},{-1,0,0},{0,-1,0},{0,0,-1} };
    
    const int MOD = 1000000007;
    const int INF = 0x3f3f3f3f;
    const long long INFF = 1LL << 60;
    const double EPS = 1e-9;
    const double OO = 1e15;
    const double PI = acos(-1.0); //M_PI;
    
    /**
        f[i][j]=max(f[i-1][k]+sum(k,j))
               =max(f[i-1][k]+sum(1,j)-sum(1,k))
               =max(f[i-1][k]-sum(1,k))+sum(1,j)
    **/
    const int maxn=111;
    const int maxm=11111;
    int n,m,X,T;
    int score[maxn][maxm];
    int f[maxn][maxm];
    int que[maxm],les[maxm];
    
    int main()
    {
        int head,tail;
        int sum,tmp;
        while (cin>>n>>m>>X>>T)
        {
            REP_1(i,n) REP_1(j,m)
                cin>>score[i][j];
            FOR_1(i,0,m) f[0][i]=-INF;
            f[0][X]=0;
            REP_1(i,n)
            {
                f[i][1]=f[i-1][1]+score[i][1];
                head=tail=0;
                les[0]=1;
                que[0]=f[i-1][1];
                sum=score[i][1];
                FOR_1(j,2,m)
                {
                    while (head<=tail&&j-les[head]>T) head++;
                    tmp=f[i-1][j]-sum;
                    while (head<=tail&&que[tail]<=tmp) tail--;
                    sum+=score[i][j];
                    tail++;
                    les[tail]=j;
                    que[tail]=tmp;
                    f[i][j]=que[head]+sum;
                }
                head=tail=0;
                les[0]=m;
                f[i][m]=max(f[i][m],f[i-1][m]+score[i][m]);
                que[0]=f[i-1][m];
                sum=score[i][m];
                DWN_1(j,m-1,1)
                {
                    while (head<=tail&&les[head]-j>T) head++;
                    tmp=f[i-1][j]-sum;
                    while (head<=tail&&que[tail]<=tmp) tail--;
                    sum+=score[i][j];
                    tail++;
                    les[tail]=j;
                    que[tail]=tmp;
                    f[i][j]=max(f[i][j],que[head]+sum);
                }
            }
            int ans=-INF;
            REP_1(i,m)
            {
                ans=max(ans,f[n][i]);
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    







  • 相关阅读:
    图像全參考客观评价算法比較
    单片机project师必备的知识
    ACM-并查集之小希的迷宫——hdu1272
    ArcGIS教程:加权总和
    九度 题目1368:二叉树中和为某一值的路径
    解决solr搜索多词匹配度和排序方案
    具体解释linux文件处理的的经常使用命令
    Hotel
    Unity3D 射线指定层获取GameObject 注意 LayerMask
    ios设计一部WindowsPhone手机
  • 原文地址:https://www.cnblogs.com/cyendra/p/3226270.html
Copyright © 2011-2022 走看看