HDU—6024(Building Shops)

来源:互联网 发布:百度的大数据 编辑:程序博客网 时间:2024/06/14 06:56

Building Shops

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


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 thesen 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
31 22 33 441 73 15 106 1
 
Sample Output
511


题意描述:杭州电子科技大学有很多空的教室被考虑建成糖果屋,现在有n间特定教室可能被建为糖果屋,但是建造糖果屋需要一定量的花费,对于这n见教室,最左边的第一个教室肯定会被建成糖果屋,然后其右边的教室m如果选择修建糖果屋,则需要承担建糖果屋的费用,如果选择不建糖果屋,则相应花费为它到最左边糖果屋的距离,现给出特定教室的坐标,求总花费最小应该怎样修建糖果屋。

解题分析:首先,修建教室时会对其后的教室产生后效性,即当前修建的教室会对后面的教室修建产生影响,故我们采用DP的思路处理该问题,创建dp[100005][2]数组存储教室信息,dp[ i ][0]表示第i间教室不修建糖果屋的总费用,dp[ i ][1]表示第 i 间教室修建糖果屋的总费用。现在推导递推式,对于第 i 间教室,假定花费为 t ,则有     
dp[ i ][1] = min( dp[ i-1][0] , dp[ i -1][1] ) + t ,对于dp[ i ][0],假定其左边最近糖果屋为第 j 间,距离为distant,则有
dp[ i ][0] = dp[ j ][1] + distant,所以,我们现在就需要找到这个第 j 间糖果屋,又糖果屋性质:dp[ j ][0] >= dp[j ][1],
所以可以通过遍历找到 j , 相应遍历方法如下(site 为教室地点):
for(j=i-1;j>=0;j--){dis = dis + (i-j)*(room[j+1].site - room[j].site);dp[i][0] = min( dp[i][0] ,(dp[j][1] + dis)); }
遍历代码解释: 从 i 的前一个教室开始遍历即 j = i - 1,如果 j 为糖果屋,则dp[ j ][0] >= dp[ j ][1],进一步可知:
dp[i][0] 最终等于dp[ j ][1] + dis,如果 j 不是糖果屋,则继续遍历,其中距离的计算是从找到的糖果屋 j 到 i 之间的所有未修糖果屋距离之和。

AC code :

#include<stdio.h>#include<iostream>#include<algorithm>const int INF = 1234567890;using namespace std;struct cla{long long  site;long long  fare;};int cmp(cla a , cla b){return(a.site  < b.site );}int main (void){int count;while(scanf("%d",&count) != EOF){int i,j;long long ans = 0;//必用long long ;long long dp[5000][2];struct cla room[5000];for(i=0;i<count;i++){scanf("%lld%lld",&room[i].site , &room[i].fare);}sort(room,room+count,cmp); dp[0][0] = INF;dp[0][1] = room[0].fare; for(i=1;i<count;i++){long long dis = 0;dp[i][0] = INF;dp[i][1] = min(dp[i-1][0] ,dp[i-1][1]) + room[i].fare ;for(j=i-1;j>=0;j--){ dis = dis + (i-j)*(room[j+1].site - room[j].site); dp[i][0] = min( dp[i][0] ,(dp[j][1] + dis)); }}ans = min(dp[count-1][0],dp[count-1][1]);printf("%lld\n",ans);}} 



原创粉丝点击