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


php

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;
}
相關文章
相關標籤/搜索