zoukankan      html  css  js  c++  java
  • hdu 4362 Dragon Ball

    题意:在M分钟里,每分钟会出现N颗龙珠,每颗龙珠的位置有题目给出,并且取走每个龙珠所消耗的能量也给出,同时在路上消耗的能量石|x1-x2|,如果在每分钟出现的龙珠里取一颗,问消耗能量最小是多少。

    思路:在比赛的时候就知道要有dp过,不过如果是不加优化的dp会超时的,所以要优化一下。先来推一下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];

    如果直接用这个状态转移公式的,时间复杂度是:m*n*n,优化的话,如果每一个状态都看成是由它左边的位置转移来的话,状态转移公式可以转变成:

    p[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]左边的上一层状态中值最小的,同理可得由它右边位置转移而来的,两者去最小。

    代码:

    View Code
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <map>
    #include <math.h>
    #define  N 1002
    #define  M 53
    #define  INF 100000000
    using namespace std ;
    
    struct node
    {
        int pos ;
        int cost ;
    }p[M][N] ;
    
    int dp[M][N] ;
    int q[N] , top , tail ;//单调队列维护最小值
    
    int cmp ( const node &a , const node &b )
    {
        return a.pos < b.pos ;
    }
    
    int cal ( int i , int k , int j )//求距离
    {
        return dp[i-1][k] + abs( p[i-1][k].pos - p[i][j].pos );
    }
    
    int main()
    {
        int cas , i , j , k , n , m , s , minx , res ;
    
        scanf ( "%d" , &cas );
        while ( cas-- )
        {
            scanf ( "%d%d%d" , &m , &n , &s );
            for ( i = 0 ; i < m ; i++ )
            {
                for ( j = 0 ; j < n ; j++ )
                scanf( "%d" , &p[i][j].pos );
            }
            for ( i = 0 ; i < m ; i++ )
            {
                for ( j = 0 ; j < n ; j++ )
                {
                    scanf ( "%d" , &p[i][j].cost );
                }
                sort( p[i] , p[i] + n , cmp );//将位置从小到大排序
            }
    
            for ( i = 0 ; i < n ; i++ )//初始化
            dp[0][i] = abs ( s - p[0][i].pos ) + p[0][i].cost ;
    
            for ( i = 1 ; i < m ; i++ )
            {
                top = 0 ;
                tail = -1 ;
                //从左边开始搜索
                for ( j = k = 0 ; j < n ; j++ )
                {
                    dp[i][j] = INF ;
                    //找最小值,有单调队列维护
                    while ( k < n && p[i-1][k].pos <= p[i][j].pos )
                    {
                        res = cal ( i , k , j );
                        while ( tail >= top && cal( i , q[tail] , j ) >= res )
                        tail-- ;
                        q[++tail] = k ;
                        k++ ;
                    }
                    if ( tail >= top )//取第一个最小值
                    dp[i][j] = cal ( i , q[top] , j );
                }
    
                top = 0 ;
                tail = -1 ;
                //从右边开始搜索
                for ( j = k = n - 1 ; j >= 0 ; j-- )
                {
                    while ( k >= 0 && p[i-1][k].pos > p[i][j].pos )
                    {
                        res = cal ( i , k , j );
                        while ( tail >= top && cal ( i , q[tail] , j ) >= res )
                        tail-- ;
                        q[++tail] = k ;
                        k-- ;
                    }
                    if ( tail >= top )
                    {
                        if ( cal ( i , q[top] , j ) < dp[i][j] )
                        dp[i][j] = cal ( i , q[top] , j );
                    }
                }
                for ( j = 0 ; j < n ; j++ )
                dp[i][j] += p[i][j].cost ;
            }
            minx = INF ;//找最小值
            for ( i = 0 ; i < n ; i++ )
            if ( dp[m-1][i] < minx )
            minx = dp[m-1][i] ;
            printf ( "%d\n" , minx );
        }
        return 0 ;
    }
  • 相关阅读:
    LeetCode 345. Reverse Vowels of a String 题解
    LeetCode 344. Reverse String 题解
    LeetCode 27. Remove Element 题解
    LeetCode 61. Rotate List 题解
    LeetCode 19.Remove Nth Node From End of List 题解
    Android耗电量
    Android 使用adb查看和修改电池信息
    Android AOP AspectJ 插桩
    Flask相关用法
    Monkey日志信息的11种Event percentage
  • 原文地址:https://www.cnblogs.com/misty1/p/2643526.html
Copyright © 2011-2022 走看看