设为首页 加入收藏

TOP

HDU 4362 Dragon Ball(维护最小值DP优化)
2015-11-21 00:55:47 来源: 作者: 【 】 浏览:1
Tags:HDU 4362 Dragon Ball 维护 最小 优化

题意: 在连续的 n 秒中,每秒会出现 m 个龙珠,出现之后会立即消失,知道了第一秒所在的位置,每从一个位置移动到另一个位置的时候,消耗的价值为 abs(i-j), 知道了次出现的龙珠的价值,问 n 秒之后得到的最大价值是多少。

思路:这道题朴素的做法时间复杂度为O(n*n*m)勉强可以水过去,正解应该是用单调队列的思路维护最小值优化。

由状态转移方程dp[i][j] = min{ dp[i-1][k] + abs(pos[i-1][k]-pos[i][j]) } + cost[i][j]

可以推出dp[i][j]+pos[i][j]+cost[i][j] = min(dp[i-1][k]+pos[i-1][k]) (当pos[i-1][k]>pos[i][j]))

所以可以按位置排序后维护dp[i-1][k]+pos[i-1][k])的最小值。

?

#include
  
     
#include
   
     #include
    
      #include
     
       #include
      
        #include
       
         #include
        
          #include
          #include
          
            #include
           
             #include
            
              #include
              #include
              
                #define eps 1e-6 #define LL long long #define pii (pair
               
                ) //#pragma comment(linker, /STACK:1024000000,1024000000) using namespace std; const LL INF = 1000000000000000; int n, m; LL x; struct Period { LL pos, e, dp; bool operator < (const Period& A) const { return pos < A.pos; } } node[55][1005]; int main() { // freopen(input.txt, r, stdin); int T; cin >> T; while(T--) { scanf(%d%d%I64d, &m, &n, &x); for(int i = 1; i <= m; i++) for(int j = 1; j <= n; j++) scanf(%I64d, &node[i][j].pos); for(int i = 1; i <= m; i++) for(int j = 1; j <= n; j++) scanf(%I64d, &node[i][j].e); for(int i = 1; i <= n; i++) node[1][i].dp = abs(node[1][i].pos-x)+node[1][i].e; sort(node[1]+1, node[1]+1+n); for(int i = 2; i <= m; i++) { sort(node[i]+1, node[i]+1+n); int cur = 1; LL t = INF; for(int j = 1; j <= n; j++) { while(cur <= n && node[i-1][cur].pos <= node[i][j].pos) { t = min(t, node[i-1][cur].dp-node[i-1][cur].pos); cur++; } node[i][j].dp = t+node[i][j].e+node[i][j].pos; } cur = n; t = INF; for(int j = n; j >= 1; j--) { while(cur>=1 && node[i-1][cur].pos >= node[i][j].pos) { t = min(t, node[i-1][cur].dp+node[i-1][cur].pos); cur--; } node[i][j].dp = min(node[i][j].dp, t+node[i][j].e-node[i][j].pos); } } LL ans = INF; for(int i = 1; i <= n; i++) ans = min(ans, node[m][i].dp); cout << ans << endl; } return 0; } 
               
              
            
           
          
        
       
      
     
    
   
  

?

?

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇poj1228 Grandpa's Estate 凸.. 下一篇HDOJ 5358 First One 暴力

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: