zoukankan      html  css  js  c++  java
  • HDU 4362 Dragon Ball 贪心DP

    Dragon Ball

    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
     

    题意:

      给你m天,每天在任意的一位坐标轴上出现n个球pos[i][j],0时间的时候在x位置,

      从x走向y花费abs(x-y)的价值,拿掉这个球花费cost[i][j]

      问你每次时间你都必须走向一个球拿掉它,m天后 最小花费是多少

    题解:

      设定dp[i][j]表示第i天后在第j个球的最小花费,

      容易想到这是一个n*m*n的转移

      给了1.5s,值得一试

      不过你把转移方程写出来:

          对于从当前位置左边转移过来的 dp[i][j] = dp[i-1][k] - pos[i-1][k] + pos[i][j] + cost[i][j];

        对于从当前位置右边转移过来的  dp[i][j] = dp[i-1][k] + pos[i-1][k]  -pos[i][j] + cos[i][j];

      其中dp[i-1][k],pos[i-1][k];都是上一层的,这个我们预处理出就好了啊

      即使 dp[i-1][k] - pos[i-1][k] 维护最小  dp[i-1][k] + pos[i-1][k]维护最小,再二分取两者最小就可以了

      求个前缀的事。。。。

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    using namespace std;
    const int N = 1e3+20, M = 1e4, mod = 1000000007,inf = 1e9;
    typedef long long ll;
    
    int dp[55][N],cost[55][N],pos[55][N],n,m,x,allpos[N],l[N],r[N];
    pair<int,int > P[N];
    int main() {
        int T;
        scanf("%d",&T);
        while(T--) {
            scanf("%d%d%d",&m,&n,&x);
            for(int i=1;i<=m;i++)
                for(int j=1;j<=n;j++) scanf("%d",&pos[i][j]);
            for(int i=1;i<=m;i++)
                for(int j=1;j<=n;j++) scanf("%d",&cost[i][j]);
    
            for(int i=1;i<=n;i++) dp[1][i] = abs(x-pos[1][i])+cost[1][i];
    
            for(int j=1;j<=n;j++)
                    P[j] = make_pair(pos[1][j],dp[1][j] - pos[1][j]);
                sort(P+1,P+n+1);
                for(int j=1;j<=n;j++) allpos[j] = P[j].first;
    
                l[0] = inf;
                r[n+1] = inf;
                for(int j=1;j<=n;j++)
                    l[j] = min(l[j-1],P[j].second);
                for(int j=1;j<=n;j++)
                    P[j] = make_pair(pos[1][j],dp[1][j] + pos[1][j]);
                sort(P+1,P+n+1);
                for(int j=n;j>=1;j--)
                    r[j] = min(r[j+1],P[j].second);
    
            for(int i=2;i<=m;i++) {
    
                for(int j=1;j<=n;j++) {
                    int tmp = upper_bound(allpos+1,allpos+n+1,pos[i][j])- allpos - 1;
                    dp[i][j] = min(l[tmp] + cost[i][j]+pos[i][j],r[tmp+1] + cost[i][j] - pos[i][j]);
                  //  cout<<dp[i][j]<<" ";
                }
                for(int j=1;j<=n;j++)
                    P[j] = make_pair(pos[i][j],dp[i][j] - pos[i][j]);
                sort(P+1,P+n+1);
                for(int j=1;j<=n;j++) allpos[j] = P[j].first;
                l[0] = inf;
                r[n+1] = inf;
                for(int j=1;j<=n;j++)
                    l[j] = min(l[j-1],P[j].second);
                for(int j=1;j<=n;j++)
                    P[j] = make_pair(pos[i][j],dp[i][j] + pos[i][j]);
                sort(P+1,P+n+1);
                for(int j=n;j>=1;j--)
                    r[j] = min(r[j+1],P[j].second);
                   // cout<<endl;
            }
            int ans = inf;
            for(int i=1;i<=n;i++) ans = min(dp[m][i],ans);
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    第六节:流上下文
    第五节:控制序列化和反序列化的数据
    第四节:格式化器如何序列化类型实例
    第三节:控制序列化和反序列化
    第二节:使类型可序列化
    第一节:序列化和反序列化快速入门
    第五节:使用反射发现类型成员
    golang 一些坑 rang
    golang json格式字符串反序列化映射到切片结构体
    golang 结构体内嵌结构体序列化填充
  • 原文地址:https://www.cnblogs.com/zxhl/p/5521847.html
Copyright © 2011-2022 走看看