zoukankan      html  css  js  c++  java
  • 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;
    }
    




  • 相关阅读:
    Android Service总结06 之AIDL
    Android Service总结05 之IntentService
    Android Service总结04 之被绑定的服务 -- Bound Service
    Android Service总结02 service介绍
    Android Service总结03 之被启动的服务 -- Started Service
    Android Service总结01 目录
    Android 数据存储04之Content Provider
    Android 数据存储03之SQLite
    Android 数据存储02之文件读写
    Android 数据存储01之SharedPreferences
  • 原文地址:https://www.cnblogs.com/cyendra/p/3226275.html
Copyright © 2011-2022 走看看