zoukankan      html  css  js  c++  java
  • HDU6024:Building Shops(简单DP)

    Building Shops

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 4446    Accepted Submission(s): 1551


    Problem Description
    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.
     
    Input
    The input contains several test cases, no more than 10 test cases.
    In each test case, the first line contains an integer n(1n3000), denoting the number of the classrooms.
    In the following n lines, each line contains two integers xi,ci(109xi,ci109), 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.
     
    Output
    For each test case, print a single line containing an integer, denoting the minimal cost.
     
    Sample Input
    3 1 2 2 3 3 4 4 1 7 3 1 5 10 6 1
     
    Sample Output
    5 11
     
    Source
     
     
    题意:
    在n个在一条线的教室里面开店,给出每个教室的位置和开店需要的钱,若该教室开店就消耗开店花的钱,不开店则消耗该教室到左边最近的开店的教室的距离的钱,不开店的教室左边一定有开店的教室,求最少花费多少钱。
    题解:
    由题意可得第一个教室一定会开店,由题目的两个状态类似背包,因此可以用DP来做,设DP[n][2],DP[n][0]代表店铺n-1没有开店花费最少的钱,DP[0][1]代表店铺n-1开店花费最少的钱。
    因此可以得一转移方程为dp[i][1] = classes[i].price + min(dp[i - 1][0], dp[i - 1][1]);。而关于dp[i][0]则可以枚举来得到最小值。
    重点:m += (i - f) * (classes[f + 1].point - classes[f].point);
    注意:该题数据应用long long!我因为这个卡了十分钟……
    具体见如下代码:
    #define _CRT_SECURE_NO_DepRECATE
    #define _CRT_SECURE_NO_WARNINGS
    #include <cstdio>
    #include <iostream>
    #include <cmath>
    #include <iomanip>
    #include <string>
    #include <algorithm>
    #include <bitset>
    #include <cstdlib>
    #include <cctype>
    #include <iterator>
    #include <vector>
    #include <cstring>
    #include <cassert>
    #include <map>
    #include <queue>
    #include <set>
    #include <stack>
    #define ll long long
    #define INF 0x3f3f3f3f
    #define ld long double
    const ld pi = acos(-1.0L), eps = 1e-8;
    int qx[4] = { 0,0,1,-1 }, qy[4] = { 1,-1,0,0 }, qxx[2] = { 1,-1 }, qyy[2] = { 1,-1 };
    using namespace std;
    struct node
    {
    	ll point, price;
    }classes[5000];
    bool cmp(node x, node y)
    {
    	return x.point < y.point;
    }
    int main()
    {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	int n;
    	ll dp[5000][2];
    	while (cin >> n)
    	{
    		memset(dp, 0, sizeof(dp));
    		for (int i = 0; i < n; i++)
    		{
    			cin >> classes[i].point >> classes[i].price;
    		}
    		sort(classes, classes + n, cmp);//题目没说按照顺序输入,所以需要先排序
    		dp[0][1] = classes[0].price;
    		dp[0][0] = INF;
    		for (int i = 1; i < n; i++)
    		{
    			dp[i][1] = classes[i].price + min(dp[i - 1][0], dp[i - 1][1]);
    			dp[i][0] = INF;
    			ll m = 0;
    			for (int f = i - 1; f >= 0; f--)//枚举出i店铺左边第一个店铺为哪个店铺的时候花费最少,从i-1开始枚举
    			{
    				m += (i - f) * (classes[f + 1].point - classes[f].point);//重点,可画图理解,m为每次往前推一点的时候增加的距离花费
    				dp[i][0] = min(dp[i][0], dp[f][1] + m);
    			}
    		}
    		cout << min(dp[n - 1][0], dp[n - 1][1]) << endl;
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    什么是根文件系统
    构建基本的嵌入式Linux根文件系统
    “文件系统”与“根文件系统”详解
    C#中NameValueCollection类用法详解
    别把西红柿连续种在同一块地里
    asp.net 服务器控件的 ID,ClientID,UniqueID 的区别
    不要为框架作过多的假设
    构件技术
    asp.net中控件id,clientid,uniqueid的区别
    系统架构图怎么画
  • 原文地址:https://www.cnblogs.com/Load-Star/p/12657092.html
Copyright © 2011-2022 走看看