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\n", 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 }