HDU 6024 Building Shops (简单dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6024

题意:有n个room在一条直线上,需要这这些room里面建造商店,如果第i个room建造,则要总花费加上Ci , 不建造的话, 总花费就要加上去左边的第一间商店的距离。求总的最小花费。

题解:dp1[i] 为第i个建造的最小花费, dp2[i] 为第i个不建造的最小花费。

   dp1[i] = min(dp1[i-1], dp2[i-1]) + Ci  

   dp2[i] = min(dp2[i], dp1[j] + dis[j][i])  j为[1, i-1]。

   j为左手边第一间商店,那么从j到i都是不建商店的,就需要加上 每一间room到商店的距离。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <algorithm>
 6 #include <cmath>
 7 #include <set>
 8 using namespace std;
 9 typedef long long LL;
10 #define ms(a, b) memset(a, b, sizeof(a))
11 #define pb push_back
12 #define mp make_pair
13 const int INF = 0x7fffffff;
14 const int inf = 0x3f3f3f3f;
15 const int mod = 1e9+7;
16 const int maxn = 3000 + 10;
17 struct node
18 {
19     LL x, c;
20 };
21 LL dp1[maxn];
22 LL dp2[maxn];
23 LL dis[maxn][maxn];
24 void init() {
25     ms(dp1, 0);
26     ms(dp2, 0);
27     ms(dis, 0);
28 }
29 bool cmp(node x1, node x2)
30 {
31     return x1.x < x2.x;
32 }
33 void solve(int n) {
34     node a[maxn];
35     for(int i=1;i<=n;i++)
36         scanf("%lld%lld", &a[i].x, &a[i].c);
37     for(int i=1;i<=n;i++)
38         a[i].x+=1000000000;
39     sort(a+1, a+n+1, cmp);
40     for(int i = 1;i<=n;i++){
41         for(int j = i+1;j<=n;j++){
42             dis[i][j] = dis[i][j-1] + (a[j].x - a[i].x);
43         }
44     }
45     dp1[1] = a[1].c;
46     dp2[1] = a[1].c;
47     for(int i = 2;i<=n;i++){
48         dp1[i] = min(dp1[i-1], dp2[i-1]) + a[i].c;
49         dp2[i] = dp1[i];
50         for(int j = i-1;j>=1;j--){
51             dp2[i] = min(dp2[i], dp1[j]+dis[j][i]);
52         }
53     }
54     printf("%lld
", min(dp1[n], dp2[n]));
55 }
56 int main() {
57 #ifdef LOCAL
58     freopen("input.txt", "r", stdin);
59 //        freopen("output.txt", "w", stdout);
60 #endif
61     int n;
62     while(~scanf("%d", &n)){
63         init();
64         solve(n);
65     }
66     return 0;
67 }
View Code
原文地址:https://www.cnblogs.com/denghaiquan/p/6984368.html