• MUTC7 C


    Dragon Ball

    Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 1680    Accepted Submission(s): 614


    Problem Description
    Sean has got a Treasure map which shows when and where the dragon balls will appear. some dragon balls will appear in a line at the same time for each period.Since the time you got one of them,the other dragon ball will disappear so he can only and must get one Dragon ball in each period.Digging out one ball he will lose some energy.Sean will lose |x-y| energy when he move from x to y.Suppose Sean has enough time to get any drogan ball he want in each period.We want to know the minimum energy sean will lose to get all period’s dragon ball.
     

    Input
    In the first line a number T indicate the number of test cases.Then for each case the first line contain 3 numbers m,n,x(1<=m<=50,1<=n<=1000),indicate m period Dragon ball will appear,n dragon balls for every period, x is the initial location of sean.Then two m*n matrix. For the first matrix,the number in I row and J column indicate the location of J-th Dragon ball in I th period.For the second matrix the number in I row and J column indicate the energy sean will lose for J-th Dragon ball in I-th period.
     

    Output
    For each case print a number means the minimum energy sean will lose.
     

    Sample Input
    1 3 2 5 2 3 4 1 1 3 1 1 1 3 4 2
     

    Sample Output
    8
     

    Author
    FZU
     

    Source
     

    Recommend
    zhuyuanchen520

    ------------

    单调队列+DP


    设dp[i][j]表示第i批龙珠中取第j个需要花费的最小体力。

    dp[i][j] = min{ dp[i-1][k] + abs(pos[i-1][k]-pos[i][j]) } + cost[i][j];

    如果枚举k的话总复杂度位m*n*n,会超时。

    可以看出若每个状态只由上一层位置在其左边的状态的转移而来的话:  

    dp[i][j]

    min { dp[i-1][k] + pos[i][j] - pos[i-1][k] } + cost[i][j]

    = min { dp[i-1][k] - pos[i-1][k] } + pos[i][j] + cost[i][j]

    dp[i-1][k]-pos[i-1][k]是个确定的值,就是相当于求位置在pos[i][j]左边的上一层状态中值最小的,可以用个单调队列维护。由右边转移来的类似,再处理一遍右边转移来的取最优。

    因为要对同一层的点排序,所以总复杂度是m*n*logn。

    -----------

    /** 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;
    
    int n,m,s;
    struct node{
        int local;
        int cost;
    }a[55][1111];
    int f[55][1111];
    /** f[i][j]=min(f[i-1][k]+abs(a[i][j].local-a[i-1][k].local)+a[i][j].cost) **/
    int head,tail;
    int que[1111];
    int dp(int i,int j,int k)
    {
        return f[i-1][k]+abs(a[i][j].local-a[i-1][k].local)+a[i][j].cost;
    }
    
    bool cmp(node a,node b)
    {
        return a.local<b.local;
    }
    
    int main()
    {
        int T;
        cin>>T;
        while (cin>>n>>m>>s)
        {
            clr(f,INF);
            REP_1(i,n) REP_1(j,m)
                cin>>a[i][j].local;
            REP_1(i,n)
            {
                REP_1(j,m) cin>>a[i][j].cost;
                sort(a[i]+1,a[i]+m+1,cmp);
            }
            REP_1(i,m)
            {
                f[1][i]=abs(s-a[1][i].local)+a[1][i].cost;
            }
            FOR_1(i,2,n)
            {
                head=tail=0;
                int k=1;
                FOR_1(j,1,m)
                {
                    while (k<=m&&a[i-1][k].local<=a[i][j].local)
                    {
                        int t=dp(i,j,k);
                        while (head<tail&&dp(i,j,que[tail-1])>=t) tail--;
                        que[tail++]=k;
                        k++;
                    }
                    if (head<tail) f[i][j]=dp(i,j,que[head]);
                }
                head=tail=0;
                k=m;
                DWN_1(j,m,1)
                {
                    while (k>=1&&a[i-1][k].local>a[i][j].local)
                    {
                        int t=dp(i,j,k);
                        while (head<tail&&dp(i,j,que[tail-1])>=t) tail--;
                        que[tail++]=k;
                        k--;
                    }
                    if (head<tail) f[i][j]=min(f[i][j],dp(i,j,que[head]));
                }
            }
            int ans=INF;
            REP_1(i,m)
            {
                ans=min(ans,f[n][i]);
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    




  • 相关阅读:
    高级程序设计语言学习2
    程序设计语言学习
    基于Android,对硬件、框架、API、操作系统、应用程序的理解
    Python_code_使用OpenCV库对图片实现数据增强
    Python_code_使用ImageFilter库对图片实现数据增强
    Python_code_实现贴图功能
    Python_code_使用OpenCV库实现对图像的_平移_旋转_缩放
    Python_code_七段数码管绘制实现_happy-new-year
    3_一幅图像,经过傅里叶变换后,将高频部分删除,再进行反变换,设想一下将会得到什么结果?
    2_图像处理中正交变换的目的是什么?图像变换主要用于那些方面?
  • 原文地址:https://www.cnblogs.com/cyendra/p/3226275.html
Copyright © 2020-2023  润新知