HDU 6024 Building Shops(DP)

3 篇文章 0 订阅
1 篇文章 0 订阅

HDU 6024 Building Shops(DP)

描述:

HDU’s n classrooms are on a line ,which can be considered as a number line. Each classroom has a coordinate. Now Little Q wants to build several candy shops in these n classrooms.

The total cost consists of two parts. Building a candy shop at classroom i would have some cost ci. For every classroom P without any candy shop, then the distance between P and the rightmost classroom with a candy shop on P’s left side would be included in the cost too. Obviously, if there is a classroom without any candy shop, there must be a candy shop on its left side.

Now Little Q wants to know how to build the candy shops with the minimal cost. Please write a program to help him.

输入:

The input contains several test cases, no more than 10 test cases.
In each test case, the first line contains an integer n(1≤n≤3000), denoting the number of the classrooms.
In the following n lines, each line contains two integers xi,ci(−109≤xi,ci≤109), denoting the coordinate of the i-th classroom and the cost of building a candy shop in it.
There are no two classrooms having same coordinate.

输出:

For each test case, print a single line containing an integer, denoting the minimal cost.

样例输入:

3
1 2
2 3
3 4
4
1 7
3 1
5 10
6 1

输出:

5
11

参考自:http://blog.csdn.net/DorMOUSENone/article/details/71439463

题意:

  • 学校有n间房子排成一列,有各自的坐标。然后现在需要在这些房子中选出一些房子来建造糖果屋。
  • 建造糖果屋是有一定的耗费的,第一种耗费就是用第i间房子建造糖果屋需要花费ci;另一种就是,对于不是糖果屋的房子i,到这间房子左边的第一个糖果屋j的距离d(i,j)也算作花费。
  • 现在要使得花费最小。(第一件房子必定为糖果屋)

思路

  • 错误解法:最开始很蠢,认为只需要一维,然后从左到右扫一遍,第i间房子建不建立糖果屋仅需要判断建立的总花费和不建立的总花费谁最下即可。其实这样不满足无后效性,因为房子建不建立糖果屋在过程中其实是无法确定的,有可能你判断第i间房子不建立比较划算,但是到了i+1间却发现其实第i间房子建立糖果屋划算。

  • 正确解法:然后发现其实过程中房子是否建立糖果屋是不确定的,所以我们使用二维dp[i][j],表示到第i间房子,最右边的糖果屋是第j间。然后一个n^2算法。状态转移为:

  • i != j ,dp[i][j] = dp[i-1][j] + 第i间房到第j间房的距离d(j,i)

  • i == j ,dp[i][i] = 第i间房的花费 + min(dp[i-1][k]) , (1<=k<i)

  • 最后取min(dp[n][j])即可。


AC代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;

    const int maxn = 3010;
    struct Node{
        long long  x;
        long long c;
    }map[maxn];
    long long dp[maxn][maxn];       //前i间教室,最右边是j号教室的最小费用   

    bool cmp(Node a,Node b)
    {
        return a.x < b.x;
    }

    int main()
    {
        int n,i,k,j;
        while(scanf("%d",&n)!=EOF)
        {
            memset(dp,0,sizeof(dp));

            for(i = 1; i <= n ;i ++)
                scanf("%lld%lld",&map[i].x,&map[i].c);

            sort(map+1,map+n+1,cmp);    

            //初始条件
            dp[1][1] = map[1].c; 

            for(i = 2; i <= n;i ++) 
            {
                for(j = 1;j<i;j++)
                    dp[i][j] = dp[i-1][j] + map[i].x - map[j].x;  //最右边是j   

                //算dp[i][i] 就是第i个本身建造 
                dp[i][i] = 1 << 30;
                for(k = 1; k < i ;k ++)
                    dp[i][i] = min(dp[i][i], dp[i-1][k] + map[i].c);
            } 

            long long ans = 1 << 30;
            for(i = 1;i<=n;i++)
                ans = min(ans,dp[n][i]);

            printf("%lld\n",ans);
        }
        return 0;
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值