题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6024
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(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. 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 2017中国大学生程序设计竞赛 - 女生专场
题目大意:有N个教室,需要在教室建糖果店,所需要的花费有两种情况
1.建糖果店所需要花费的费用。
2.这个点离左边最近的糖果店的距离。
分析:这个点有两种可能 建糖果店 不建糖果店 所以是道dp题
设dp【i】【0】表示在这个点建立糖果店所需要花费的最小费用,dp【i】【0】在这个点不建糖果店所需要花费的最小费用
dp【i】【1】=min(dp[i-1][1],dp[i-1][0])+ci;
dp[i][0]的情况需要从起点到开始枚举,所以时间复杂度为O(n*n);
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<math.h> #include<queue> #include<stack> #include <vector> #include<iostream> using namespace std; #define N 50005 #define INF 0x3f3f3f3f #define LL long long LL dp[N][2]; struct node { LL x,c; }s[N]; int cmp(node a,node b) { return a.x<b.x; } int main() { int n; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) scanf("%lld %lld",&s[i].x,&s[i].c); sort(s+1,s+n+1,cmp); memset(dp,0,sizeof(dp)); dp[1][1] = s[1].c;///东边肯定有糖果店 所以第一个教室是必须建糖果店的 dp[1][0] = INF; for(int i=2;i<=n;i++) { dp[i][1] = min(dp[i-1][1],dp[i-1][0])+s[i].c; ///在这个教室建立糖果店所需要的最小花费 LL sum=0; dp[i][0] = INF; ///找到前面花费最小的糖果店 for(int j=i-1;j>=1;j--) { sum+=(i-j)*(s[j+1].x-s[j].x); dp[i][0] = min(dp[i][0],dp[j][1]+sum); } } printf("%lld\n",min(dp[n][1],dp[n][0])); ///取建糖果店与不建糖果店的其中的小值 } return 0; }
时间: 2024-11-06 07:19:02